001    package ezvcard.io;
002    
003    import java.io.File;
004    import java.io.FileWriter;
005    import java.io.IOException;
006    import java.io.OutputStream;
007    import java.io.OutputStreamWriter;
008    import java.io.StringWriter;
009    import java.io.Writer;
010    import java.util.ArrayList;
011    import java.util.HashMap;
012    import java.util.List;
013    import java.util.Map;
014    
015    import ezvcard.Ezvcard;
016    import ezvcard.VCard;
017    import ezvcard.parameters.ImageTypeParameter;
018    import ezvcard.types.PhotoType;
019    import ezvcard.util.DataUri;
020    import ezvcard.util.IOUtils;
021    import freemarker.template.Configuration;
022    import freemarker.template.DefaultObjectWrapper;
023    import freemarker.template.Template;
024    import freemarker.template.TemplateException;
025    
026    /*
027     Copyright (c) 2012, Michael Angstadt
028     All rights reserved.
029    
030     Redistribution and use in source and binary forms, with or without
031     modification, are permitted provided that the following conditions are met: 
032    
033     1. Redistributions of source code must retain the above copyright notice, this
034     list of conditions and the following disclaimer. 
035     2. Redistributions in binary form must reproduce the above copyright notice,
036     this list of conditions and the following disclaimer in the documentation
037     and/or other materials provided with the distribution. 
038    
039     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
040     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
041     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
042     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
043     ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
044     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
045     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
046     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
047     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
048     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
049    
050     The views and conclusions contained in the software and documentation are those
051     of the authors and should not be interpreted as representing official policies, 
052     either expressed or implied, of the FreeBSD Project.
053     */
054    
055    /**
056     * Writes vCards to an HTML page (hCard format).
057     * @author Michael Angstadt
058     * @see <a
059     * href="http://microformats.org/wiki/hcard">http://microformats.org/wiki/hcard</a>
060     */
061    public class HCardPage {
062            protected static final Template template;
063            static {
064                    Configuration cfg = new Configuration();
065                    cfg.setClassForTemplateLoading(HCardPage.class, "");
066                    cfg.setObjectWrapper(new DefaultObjectWrapper());
067                    cfg.setWhitespaceStripping(true);
068                    try {
069                            template = cfg.getTemplate("hcard-template.html");
070                    } catch (IOException e) {
071                            //should never be thrown because it's always on the classpath
072                            throw new RuntimeException(e);
073                    }
074            }
075    
076            protected final List<VCard> vcards = new ArrayList<VCard>();
077    
078            /**
079             * Adds a vCard to the HTML page.
080             * @param vcard the vCard to add
081             */
082            public void addVCard(VCard vcard) {
083                    vcards.add(vcard);
084            }
085    
086            /**
087             * Writes the HTML document to a string.
088             * @return the HTML document
089             * @throws TemplateException if there's a problem with the freemarker
090             * template
091             */
092            public String write() throws TemplateException {
093                    StringWriter sw = new StringWriter();
094                    try {
095                            write(sw);
096                    } catch (IOException e) {
097                            //never thrown because we're writing to a string
098                    }
099                    return sw.toString();
100            }
101    
102            /**
103             * Writes the HTML document to an output stream.
104             * @param out the output stream
105             * @throws IOException if there's a problem writing to the output stream
106             * @throws TemplateException if there's a problem with the freemarker
107             * template
108             */
109            public void write(OutputStream out) throws IOException, TemplateException {
110                    write(new OutputStreamWriter(out));
111            }
112    
113            /**
114             * Writes the HTML document to a file.
115             * @param file the file
116             * @throws IOException if there's a problem writing to the file
117             * @throws TemplateException if there's a problem with the freemarker
118             * template
119             */
120            public void write(File file) throws IOException, TemplateException {
121                    FileWriter writer = null;
122                    try {
123                            writer = new FileWriter(file);
124                            write(writer);
125                    } finally {
126                            IOUtils.closeQuietly(writer);
127                    }
128            }
129    
130            /**
131             * Writes the HTML document to a writer.
132             * @param writer the writer
133             * @throws IOException if there's a problem writing to the writer
134             * @throws TemplateException if there's a problem with the freemarker
135             * template
136             */
137            public void write(Writer writer) throws IOException, TemplateException {
138                    Map<String, Object> map = new HashMap<String, Object>();
139                    map.put("vcards", vcards);
140                    map.put("dataUri", new DataUriGenerator());
141                    map.put("translucentBg", readImage("translucent-bg.png", ImageTypeParameter.PNG));
142                    map.put("noProfile", readImage("no-profile.png", ImageTypeParameter.PNG));
143                    map.put("ezVCardVersion", Ezvcard.VERSION);
144                    map.put("ezVCardUrl", Ezvcard.URL);
145                    template.process(map, writer);
146                    writer.flush();
147            }
148    
149            /**
150             * Reads an image from the classpath.
151             * @param name the file name, relative to this class
152             * @param mediaType the media type of the image
153             * @return the image
154             * @throws IOException
155             */
156            protected PhotoType readImage(String name, ImageTypeParameter mediaType) throws IOException {
157                    return new PhotoType(getClass().getResourceAsStream(name), mediaType);
158            }
159    
160            /**
161             * Generates data URIs for the freemarker template.
162             */
163            public static class DataUriGenerator {
164                    public String generate(String contentType, byte[] data) {
165                            return new DataUri(contentType, data).toString();
166                    }
167            }
168    }