001    package ezvcard.types;
002    
003    import java.util.List;
004    import java.util.Set;
005    
006    import ezvcard.VCard;
007    import ezvcard.VCardSubTypes;
008    import ezvcard.VCardVersion;
009    import ezvcard.io.CompatibilityMode;
010    import ezvcard.io.EmbeddedVCardException;
011    import ezvcard.io.SkipMeException;
012    import ezvcard.parameters.ValueParameter;
013    import ezvcard.util.HCardElement;
014    import ezvcard.util.VCardStringUtils;
015    
016    /*
017     Copyright (c) 2012, Michael Angstadt
018     All rights reserved.
019    
020     Redistribution and use in source and binary forms, with or without
021     modification, are permitted provided that the following conditions are met: 
022    
023     1. Redistributions of source code must retain the above copyright notice, this
024     list of conditions and the following disclaimer. 
025     2. Redistributions in binary form must reproduce the above copyright notice,
026     this list of conditions and the following disclaimer in the documentation
027     and/or other materials provided with the distribution. 
028    
029     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
030     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
031     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
032     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
033     ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
034     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
035     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
036     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
037     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
038     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
039    
040     The views and conclusions contained in the software and documentation are those
041     of the authors and should not be interpreted as representing official policies, 
042     either expressed or implied, of the FreeBSD Project.
043     */
044    
045    /**
046     * An embedded vCard or URL containing the information of someone who represents
047     * the person.
048     * 
049     * <pre>
050     * //URL
051     * VCard vcard = new VCard();
052     * AgentType agent = new AgentType(&quot;http://mi5.gov.uk/007&quot;);
053     * vcard.setAgent(agent);
054     * 
055     * //vCard
056     * VCard vcard = new VCard();
057     * VCard agentVcard = new VCard();
058     * agentVcard.setFormattedName(new FormattedNameType(&quot;Agent 007&quot;));
059     * AgentType agent = new AgentType(agentVcard);
060     * vcard.setAgent(agent);
061     * </pre>
062     * 
063     * <p>
064     * vCard property name: AGENT
065     * </p>
066     * <p>
067     * vCard versions: 2.1, 3.0
068     * </p>
069     * 
070     * @author Michael Angstadt
071     */
072    public class AgentType extends VCardType {
073            public static final String NAME = "AGENT";
074    
075            private String url;
076            private VCard vcard;
077    
078            public AgentType() {
079                    super(NAME);
080            }
081    
082            /**
083             * @param url a URL pointing to the agent's information
084             */
085            public AgentType(String url) {
086                    super(NAME);
087                    setUrl(url);
088            }
089    
090            /**
091             * @param vcard a vCard containing the agent's information
092             */
093            public AgentType(VCard vcard) {
094                    super(NAME);
095                    setVCard(vcard);
096            }
097    
098            /**
099             * Gets the URL to the agent's information.
100             * @return the URL or null if not set
101             */
102            public String getUrl() {
103                    return url;
104            }
105    
106            /**
107             * Sets the URL to the agent's information.
108             * @param url the URL
109             */
110            public void setUrl(String url) {
111                    this.url = url;
112                    vcard = null;
113            }
114    
115            /**
116             * Gets an embedded vCard with the agent's information.
117             * @return the vCard or null if not set
118             */
119            public VCard getVCard() {
120                    return vcard;
121            }
122    
123            /**
124             * Sets an embedded vCard with the agent's information.
125             * @param vcard the vCard
126             */
127            public void setVCard(VCard vcard) {
128                    this.vcard = vcard;
129                    url = null;
130            }
131    
132            @Override
133            public VCardVersion[] getSupportedVersions() {
134                    return new VCardVersion[] { VCardVersion.V2_1, VCardVersion.V3_0 };
135            }
136    
137            @Override
138            protected void doMarshalSubTypes(VCardSubTypes copy, VCardVersion version, List<String> warnings, CompatibilityMode compatibilityMode, VCard vcard) {
139                    if (url != null) {
140                            ValueParameter vp = (version == VCardVersion.V2_1) ? ValueParameter.URL : ValueParameter.URI;
141                            copy.setValue(vp);
142                    } else {
143                            copy.setValue(null);
144                    }
145            }
146    
147            @Override
148            protected void doMarshalText(StringBuilder sb, VCardVersion version, List<String> warnings, CompatibilityMode compatibilityMode) {
149                    if (url != null) {
150                            sb.append(url);
151                    } else if (vcard != null) {
152                            throw new EmbeddedVCardException(vcard);
153                    } else {
154                            throw new SkipMeException("Property has neither a URL nor an embedded vCard.");
155                    }
156            }
157    
158            @Override
159            protected void doUnmarshalText(String value, VCardVersion version, List<String> warnings, CompatibilityMode compatibilityMode) {
160                    if (subTypes.getValue() != null) {
161                            setUrl(VCardStringUtils.unescape(value));
162                    } else {
163                            throw new EmbeddedVCardException(new Injector());
164                    }
165            }
166    
167            @Override
168            protected void doUnmarshalHtml(HCardElement element, List<String> warnings) {
169                    Set<String> classes = element.classNames();
170                    if (classes.contains("vcard")) {
171                            throw new EmbeddedVCardException(new Injector());
172                    } else {
173                            String href = element.absUrl("href");
174                            if (href.length() > 0) {
175                                    setUrl(element.value());
176                            }
177                    }
178            }
179    
180            private class Injector implements EmbeddedVCardException.InjectionCallback {
181                    public void injectVCard(VCard vcard) {
182                            setVCard(vcard);
183                    }
184            }
185    }