001    package ezvcard.io.scribe;
002    
003    import java.util.List;
004    
005    import ezvcard.io.CannotParseException;
006    import ezvcard.io.html.HCardElement;
007    import ezvcard.parameter.SoundType;
008    import ezvcard.property.Sound;
009    import ezvcard.util.DataUri;
010    
011    /*
012     Copyright (c) 2013, Michael Angstadt
013     All rights reserved.
014    
015     Redistribution and use in source and binary forms, with or without
016     modification, are permitted provided that the following conditions are met: 
017    
018     1. Redistributions of source code must retain the above copyright notice, this
019     list of conditions and the following disclaimer. 
020     2. Redistributions in binary form must reproduce the above copyright notice,
021     this list of conditions and the following disclaimer in the documentation
022     and/or other materials provided with the distribution. 
023    
024     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
025     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
026     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
027     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
028     ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
029     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
030     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
031     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
032     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
033     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
034     */
035    
036    /**
037     * Marshals {@link Sound} properties.
038     * @author Michael Angstadt
039     */
040    public class SoundScribe extends BinaryPropertyScribe<Sound, SoundType> {
041            public SoundScribe() {
042                    super(Sound.class, "SOUND");
043            }
044    
045            @Override
046            protected SoundType _buildTypeObj(String type) {
047                    return SoundType.get(type, null, null);
048            }
049    
050            @Override
051            protected SoundType _buildMediaTypeObj(String mediaType) {
052                    return SoundType.get(null, mediaType, null);
053            }
054    
055            @Override
056            protected Sound _newInstance(String uri, SoundType contentType) {
057                    return new Sound(uri, contentType);
058            }
059    
060            @Override
061            protected Sound _newInstance(byte[] data, SoundType contentType) {
062                    return new Sound(data, contentType);
063            }
064    
065            @Override
066            protected Sound _parseHtml(HCardElement element, List<String> warnings) {
067                    String elementName = element.tagName();
068                    if (!"audio".equals(elementName) && !"source".equals(elementName)) {
069                            return super._parseHtml(element, warnings);
070                    }
071    
072                    if ("audio".equals(elementName)) {
073                            //parse its child "<source>" element
074                            org.jsoup.nodes.Element source = element.getElement().getElementsByTag("source").first();
075                            if (source == null) {
076                                    throw new CannotParseException(16);
077                            }
078    
079                            element = new HCardElement(source);
080                    }
081    
082                    String src = element.absUrl("src");
083                    if (src.length() == 0) {
084                            throw new CannotParseException(17);
085                    }
086    
087                    String type = element.attr("type");
088                    SoundType mediaType = (type.length() == 0) ? null : _buildMediaTypeObj(type);
089    
090                    try {
091                            DataUri uri = new DataUri(src);
092                            mediaType = _buildMediaTypeObj(uri.getContentType());
093                            return new Sound(uri.getData(), mediaType);
094                    } catch (IllegalArgumentException e) {
095                            //not a data URI
096                            //TODO create buildTypeObjFromExtension() method
097                            return new Sound(src, null);
098                    }
099            }
100    }