001    package ezvcard.io.scribe;
002    
003    import java.util.List;
004    
005    import ezvcard.VCard;
006    import ezvcard.VCardDataType;
007    import ezvcard.VCardVersion;
008    import ezvcard.io.html.HCardElement;
009    import ezvcard.io.json.JCardValue;
010    import ezvcard.io.xml.XCardElement;
011    import ezvcard.parameter.VCardParameters;
012    import ezvcard.property.Address;
013    
014    /*
015     Copyright (c) 2013, Michael Angstadt
016     All rights reserved.
017    
018     Redistribution and use in source and binary forms, with or without
019     modification, are permitted provided that the following conditions are met: 
020    
021     1. Redistributions of source code must retain the above copyright notice, this
022     list of conditions and the following disclaimer. 
023     2. Redistributions in binary form must reproduce the above copyright notice,
024     this list of conditions and the following disclaimer in the documentation
025     and/or other materials provided with the distribution. 
026    
027     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
028     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
029     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
030     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
031     ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
032     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
033     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
034     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
035     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
036     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
037     */
038    
039    /**
040     * Marshals {@link Address} properties.
041     * @author Michael Angstadt
042     */
043    public class AddressScribe extends VCardPropertyScribe<Address> {
044            public AddressScribe() {
045                    super(Address.class, "ADR");
046            }
047    
048            @Override
049            protected VCardDataType _defaultDataType(VCardVersion version) {
050                    return VCardDataType.TEXT;
051            }
052    
053            @Override
054            protected void _prepareParameters(Address property, VCardParameters copy, VCardVersion version, VCard vcard) {
055                    handlePrefParam(property, copy, version, vcard);
056    
057                    if (version == VCardVersion.V2_1 || version == VCardVersion.V3_0) {
058                            //remove the LABEL parameter
059                            //by the time this line of code is reached, VCardWriter will have created a LABEL property from this property's LABEL parameter
060                            copy.removeAll("LABEL");
061                    }
062            }
063    
064            @Override
065            protected String _writeText(Address property, VCardVersion version) {
066                    //@formatter:off
067                    return structured(
068                            property.getPoBox(),
069                            property.getExtendedAddress(),
070                            property.getStreetAddress(),
071                            property.getLocality(),
072                            property.getRegion(),
073                            property.getPostalCode(),
074                            property.getCountry()
075                    );
076                    //@formatter:on
077            }
078    
079            @Override
080            protected Address _parseText(String value, VCardDataType dataType, VCardVersion version, VCardParameters parameters, List<String> warnings) {
081                    Address property = new Address();
082                    StructuredIterator it = structured(value);
083    
084                    property.setPoBox(it.nextString());
085                    property.setExtendedAddress(it.nextString());
086                    property.setStreetAddress(it.nextString());
087                    property.setLocality(it.nextString());
088                    property.setRegion(it.nextString());
089                    property.setPostalCode(it.nextString());
090                    property.setCountry(it.nextString());
091    
092                    return property;
093            }
094    
095            @Override
096            protected void _writeXml(Address property, XCardElement parent) {
097                    parent.append("pobox", property.getPoBox()); //Note: The XML element must always be added, even if the value is null
098                    parent.append("ext", property.getExtendedAddress());
099                    parent.append("street", property.getStreetAddress());
100                    parent.append("locality", property.getLocality());
101                    parent.append("region", property.getRegion());
102                    parent.append("code", property.getPostalCode());
103                    parent.append("country", property.getCountry());
104            }
105    
106            @Override
107            protected Address _parseXml(XCardElement element, VCardParameters parameters, List<String> warnings) {
108                    Address property = new Address();
109                    property.setPoBox(sanitizeXml(element, "pobox"));
110                    property.setExtendedAddress(sanitizeXml(element, "ext"));
111                    property.setStreetAddress(sanitizeXml(element, "street"));
112                    property.setLocality(sanitizeXml(element, "locality"));
113                    property.setRegion(sanitizeXml(element, "region"));
114                    property.setPostalCode(sanitizeXml(element, "code"));
115                    property.setCountry(sanitizeXml(element, "country"));
116                    return property;
117            }
118    
119            private String sanitizeXml(XCardElement element, String name) {
120                    String value = element.first(name);
121                    return (value == null || value.length() == 0) ? null : value;
122            }
123    
124            @Override
125            protected Address _parseHtml(HCardElement element, List<String> warnings) {
126                    Address property = new Address();
127                    property.setPoBox(element.firstValue("post-office-box"));
128                    property.setExtendedAddress(element.firstValue("extended-address"));
129                    property.setStreetAddress(element.firstValue("street-address"));
130                    property.setLocality(element.firstValue("locality"));
131                    property.setRegion(element.firstValue("region"));
132                    property.setPostalCode(element.firstValue("postal-code"));
133                    property.setCountry(element.firstValue("country-name"));
134    
135                    List<String> types = element.types();
136                    for (String type : types) {
137                            property.getParameters().addType(type);
138                    }
139    
140                    return property;
141            }
142    
143            @Override
144            protected JCardValue _writeJson(Address property) {
145                    //@formatter:off
146                    return JCardValue.structured(
147                            property.getPoBox(),
148                            property.getExtendedAddress(),
149                            property.getStreetAddress(),
150                            property.getLocality(),
151                            property.getRegion(),
152                            property.getPostalCode(),
153                            property.getCountry()
154                    );
155                    //@formatter:on
156            }
157    
158            @Override
159            protected Address _parseJson(JCardValue value, VCardDataType dataType, VCardParameters parameters, List<String> warnings) {
160                    Address property = new Address();
161                    StructuredIterator it = structured(value);
162    
163                    property.setPoBox(it.nextString());
164                    property.setExtendedAddress(it.nextString());
165                    property.setStreetAddress(it.nextString());
166                    property.setLocality(it.nextString());
167                    property.setRegion(it.nextString());
168                    property.setPostalCode(it.nextString());
169                    property.setCountry(it.nextString());
170    
171                    return property;
172            }
173    }