001    package ezvcard.io.scribe;
002    
003    import java.util.List;
004    
005    import ezvcard.Messages;
006    import ezvcard.VCard;
007    import ezvcard.VCardDataType;
008    import ezvcard.VCardVersion;
009    import ezvcard.io.html.HCardElement;
010    import ezvcard.io.json.JCardValue;
011    import ezvcard.io.xml.XCardElement;
012    import ezvcard.parameter.VCardParameters;
013    import ezvcard.property.Telephone;
014    import ezvcard.util.TelUri;
015    
016    /*
017     Copyright (c) 2013, 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    
041    /**
042     * Marshals {@link Telephone} properties.
043     * @author Michael Angstadt
044     */
045    public class TelephoneScribe extends VCardPropertyScribe<Telephone> {
046            public TelephoneScribe() {
047                    super(Telephone.class, "TEL");
048            }
049    
050            @Override
051            protected VCardDataType _defaultDataType(VCardVersion version) {
052                    return VCardDataType.TEXT;
053            }
054    
055            @Override
056            protected VCardDataType _dataType(Telephone property, VCardVersion version) {
057                    if (version == VCardVersion.V4_0) {
058                            if (property.getText() != null) {
059                                    return VCardDataType.TEXT;
060                            }
061                            if (property.getUri() != null) {
062                                    return VCardDataType.URI;
063                            }
064                    }
065    
066                    return VCardDataType.TEXT;
067            }
068    
069            @Override
070            protected void _prepareParameters(Telephone property, VCardParameters copy, VCardVersion version, VCard vcard) {
071                    handlePrefParam(property, copy, version, vcard);
072            }
073    
074            @Override
075            protected String _writeText(Telephone property, VCardVersion version) {
076                    String text = property.getText();
077                    if (text != null) {
078                            return escape(text);
079                    }
080    
081                    TelUri uri = property.getUri();
082                    if (uri != null) {
083                            if (version == VCardVersion.V4_0) {
084                                    return uri.toString();
085                            }
086    
087                            String ext = uri.getExtension();
088                            if (ext == null) {
089                                    return escape(uri.getNumber());
090                            }
091                            return escape(uri.getNumber() + " x" + ext);
092                    }
093    
094                    return "";
095            }
096    
097            @Override
098            protected Telephone _parseText(String value, VCardDataType dataType, VCardVersion version, VCardParameters parameters, List<String> warnings) {
099                    value = unescape(value);
100                    return parse(value, dataType, warnings);
101            }
102    
103            @Override
104            protected void _writeXml(Telephone property, XCardElement parent) {
105                    String text = property.getText();
106                    if (text != null) {
107                            parent.append(VCardDataType.TEXT, text);
108                            return;
109                    }
110    
111                    TelUri uri = property.getUri();
112                    if (uri != null) {
113                            parent.append(VCardDataType.URI, uri.toString());
114                            return;
115                    }
116    
117                    parent.append(VCardDataType.TEXT, "");
118            }
119    
120            @Override
121            protected Telephone _parseXml(XCardElement element, VCardParameters parameters, List<String> warnings) {
122                    String text = element.first(VCardDataType.TEXT);
123                    if (text != null) {
124                            return new Telephone(text);
125                    }
126    
127                    String uri = element.first(VCardDataType.URI);
128                    if (uri != null) {
129                            try {
130                                    return new Telephone(TelUri.parse(uri));
131                            } catch (IllegalArgumentException e) {
132                                    warnings.add(Messages.INSTANCE.getParseMessage(18));
133                                    return new Telephone(uri);
134                            }
135                    }
136    
137                    throw missingXmlElements(VCardDataType.TEXT, VCardDataType.URI);
138            }
139    
140            @Override
141            protected Telephone _parseHtml(HCardElement element, List<String> warnings) {
142                    Telephone property;
143                    String href = element.attr("href");
144                    try {
145                            property = new Telephone(TelUri.parse(href));
146                    } catch (IllegalArgumentException e) {
147                            //not a tel URI
148                            property = new Telephone(element.value());
149                    }
150    
151                    List<String> types = element.types();
152                    for (String type : types) {
153                            property.getParameters().addType(type);
154                    }
155    
156                    return property;
157            }
158    
159            @Override
160            protected JCardValue _writeJson(Telephone property) {
161                    String text = property.getText();
162                    if (text != null) {
163                            return JCardValue.single(text);
164                    }
165    
166                    TelUri uri = property.getUri();
167                    if (uri != null) {
168                            return JCardValue.single(uri.toString());
169                    }
170    
171                    return JCardValue.single("");
172            }
173    
174            @Override
175            protected Telephone _parseJson(JCardValue value, VCardDataType dataType, VCardParameters parameters, List<String> warnings) {
176                    String valueStr = value.asSingle();
177                    return parse(valueStr, dataType, warnings);
178            }
179    
180            private Telephone parse(String value, VCardDataType dataType, List<String> warnings) {
181                    try {
182                            return new Telephone(TelUri.parse(value));
183                    } catch (IllegalArgumentException e) {
184                            if (dataType == VCardDataType.URI) {
185                                    warnings.add(Messages.INSTANCE.getParseMessage(18));
186                            }
187                    }
188    
189                    return new Telephone(value);
190            }
191    }