001/*
002 * flattr4j - A Java library for Flattr
003 *
004 * Copyright (C) 2011 Richard "Shred" Körber
005 *   http://flattr4j.shredzone.org
006 *
007 * This program is free software: you can redistribute it and/or modify
008 * it under the terms of the GNU General Public License / GNU Lesser
009 * General Public License as published by the Free Software Foundation,
010 * either version 3 of the License, or (at your option) any later version.
011 *
012 * Licensed under the Apache License, Version 2.0 (the "License");
013 * you may not use this file except in compliance with the License.
014 *
015 * This program is distributed in the hope that it will be useful,
016 * but WITHOUT ANY WARRANTY; without even the implied warranty of
017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
018 */
019package org.shredzone.flattr4j.web.builder;
020
021import java.io.Serializable;
022
023import org.shredzone.flattr4j.model.Category;
024import org.shredzone.flattr4j.model.CategoryId;
025import org.shredzone.flattr4j.model.Language;
026import org.shredzone.flattr4j.model.LanguageId;
027import org.shredzone.flattr4j.model.User;
028import org.shredzone.flattr4j.model.UserId;
029import org.shredzone.flattr4j.web.ButtonType;
030
031/**
032 * Builds the JavaScript loader for the Flattr API.
033 * <p>
034 * The builder uses sensible default settings that can be changed by using its methods.
035 * All methods return a reference to the builder itself, so method calls can be
036 * daisy-chained.
037 * <p>
038 * Example: <code>String loader = new LoaderBuilder().uid("123456").toString();</code>
039 *
040 * @author Richard "Shred" Körber
041 */
042public class LoaderBuilder implements Serializable {
043    private static final long serialVersionUID = 56937818073814669L;
044
045    private String baseUrl = "http://api.flattr.com";
046    private String version = "0.6";
047    private boolean bare = false;
048    private boolean automatic = true;
049    private boolean https = false;
050    private Boolean popout = null;
051    private String uid = null;
052    private ButtonType type = null;
053    private String language = null;
054    private String category = null;
055    private String prefix = null;
056
057    /**
058     * Sets the base URL of the Flattr API. Defaults to "http://api.flattr.com". Do not
059     * change unless you know what you are doing.
060     *
061     * @param baseUrl
062     *            New Flattr API url to be used
063     */
064    public LoaderBuilder baseUrl(String baseUrl) {
065        this.baseUrl = baseUrl;
066        return this;
067    }
068
069    /**
070     * Sets the API version to be used. Usually there is no need to change the default
071     * value, so do not change unless you know what you are doing.
072     *
073     * @param version
074     *            API version to be used (e.g. "0.6")
075     */
076    public LoaderBuilder version(String version) {
077        this.version = version;
078        return this;
079    }
080
081    /**
082     * The builder will return a bare javascript, without an enclosing &lt;script&gt; tag.
083     */
084    public LoaderBuilder bare() {
085        bare = true;
086        return this;
087    }
088
089    /**
090     * The Flattr API will not be initialized automatically, but requires a manual
091     * invocation of <code>FlattrLoader.setup()</code>. By default, the API is initialized
092     * automatically on onload.
093     */
094    public LoaderBuilder manual() {
095        automatic = false;
096        return this;
097    }
098
099    /**
100     * Sets whether to override the popout default and show a popout when hovering with
101     * the mouse over the button.
102     *
103     * @param popout
104     *            {@code true}: always show a popout, {@code false}: never show a popout
105     * @since 2.2
106     */
107    public LoaderBuilder popout(boolean popout) {
108        this.popout = popout;
109        return this;
110    }
111
112    /**
113     * Use https for loading Flattr resources (javascripts, images etc). By default http
114     * is used.
115     */
116    public LoaderBuilder https() {
117        https = true;
118        return this;
119    }
120
121    /**
122     * Sets the default {@link User}.
123     *
124     * @param user
125     *            {@link UserId}
126     */
127    public LoaderBuilder user(UserId user) {
128        this.uid = user.getUserId();
129        return this;
130    }
131
132    /**
133     * Sets the default button type to be used.
134     *
135     * @param type
136     *            {@link ButtonType} to be used
137     */
138    public LoaderBuilder button(ButtonType type) {
139        this.type = type;
140        return this;
141    }
142
143    /**
144     * Sets the default {@link Language}.
145     *
146     * @param language
147     *            Default {@link LanguageId}
148     */
149    public LoaderBuilder language(LanguageId language) {
150        this.language = language.getLanguageId();
151        return this;
152    }
153
154    /**
155     * Sets the default {@link Category}.
156     *
157     * @param category
158     *            Default {@link CategoryId}
159     */
160    public LoaderBuilder category(CategoryId category) {
161        this.category = category.getCategoryId();
162        return this;
163    }
164
165    /**
166     * Sets a HTML5 key prefix. By default "data-flattr" is used.
167     *
168     * @param prefix
169     *            HTML5 key prefix. The string must start with "data-"
170     */
171    public LoaderBuilder prefix(String prefix) {
172        if (!prefix.startsWith("data-")) {
173            throw new IllegalArgumentException("prefix must start with \"data-\"");
174        }
175        this.prefix = prefix;
176        return this;
177    }
178
179    /**
180     * Builds a loader script of the current setup.
181     */
182    @Override
183    public String toString() {
184        StringBuilder sb = new StringBuilder();
185        char separator = '?';
186
187        if (!bare) {
188            sb.append("<script type=\"text/javascript\">/* <![CDATA[ */\n");
189        }
190
191        String url = baseUrl;
192        if (https) {
193            url = url.replaceFirst("^http://", "https://");
194        }
195
196        sb.append("(function() {");
197        sb.append("var s = document.createElement('script'),");
198        sb.append("t = document.getElementsByTagName('script')[0];");
199        sb.append("s.type = 'text/javascript';");
200        sb.append("s.async = true;");
201        sb.append("s.src = '").append(url).append("/js/").append(version).append("/load.js");
202
203        if (automatic) {
204            sb.append(separator).append("mode=auto");
205            separator = '&';
206        }
207
208        if (popout != null) {
209            sb.append(separator).append("popout=").append(popout.booleanValue() ? 1 : 0);
210            separator = '&';
211        }
212
213        if (uid != null) {
214            sb.append(separator).append("uid=").append(uid);
215            separator = '&';
216        }
217
218        if (type != null) {
219            sb.append(separator).append("button=");
220            switch (type) {
221            case COMPACT:
222                sb.append("compact");
223                break;
224            case DEFAULT:
225                sb.append("default");
226                break;
227            }
228            separator = '&';
229        }
230
231        if (language != null) {
232            sb.append(separator).append("language=").append(language);
233            separator = '&';
234        }
235
236        if (category != null) {
237            sb.append(separator).append("category=").append(category);
238            separator = '&';
239        }
240
241        if (prefix != null) {
242            sb.append(separator).append("html5-key-prefix=").append(prefix);
243        }
244
245        sb.append("';");
246        sb.append("t.parentNode.insertBefore(s, t);");
247        sb.append("})();");
248
249        if (!bare) {
250            sb.append("\n/* ]]> */</script>");
251        }
252
253        return sb.toString();
254    }
255
256}