com.squarespace.template.plugins.platform.SocialFormatters.java Source code

Java tutorial

Introduction

Here is the source code for com.squarespace.template.plugins.platform.SocialFormatters.java

Source

/**
 * Copyright (c) 2015 SQUARESPACE, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.squarespace.template.plugins.platform;

import static com.squarespace.template.GeneralUtils.executeTemplate;
import static com.squarespace.template.GeneralUtils.loadResource;

import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;

import com.fasterxml.jackson.databind.JsonNode;
import com.squarespace.template.Arguments;
import com.squarespace.template.BaseFormatter;
import com.squarespace.template.CodeException;
import com.squarespace.template.CodeExecuteException;
import com.squarespace.template.Compiler;
import com.squarespace.template.Context;
import com.squarespace.template.Formatter;
import com.squarespace.template.FormatterRegistry;
import com.squarespace.template.GeneralUtils;
import com.squarespace.template.Instruction;
import com.squarespace.template.StringView;
import com.squarespace.template.SymbolTable;
import com.squarespace.template.plugins.PluginDateUtils;

/**
 * Extracted from Commons library at commit ab4ba7a6f2b872a31cb6449ae9e96f5f5b30f471
 */
public class SocialFormatters implements FormatterRegistry {

    @Override
    public void registerFormatters(SymbolTable<StringView, Formatter> table) {
        table.add(new ActivateTwitterLinksFormatter());
        table.add(new CommentCountFormatter());
        table.add(new CommentLinkFormatter());
        table.add(new CommentsFormatter());
        table.add(new GoogleCalendarUrlFormatter());
        table.add(new LikeButtonFormatter());
        table.add(new SocialButtonFormatter());
        table.add(new SocialButtonInlineFormatter());
        table.add(new TwitterFollowButtonFormatter());
    }

    private static final String CALENDAR_DATE_FORMAT = "%Y%m%dT%H%M%SZ";

    private static final Pattern TWITTER_LINKS_REGEX = Pattern.compile(
            "(\\b(https?|ftp|file):\\/\\/[-A-Z0-9+&@#\\/%?=~_|!:,.;]*[-A-Z0-9+&@#\\/%=~_|])",
            Pattern.CASE_INSENSITIVE);

    private static final String TWITTER_LINKS_REPLACE = "<a target=\"new\" href=\"$1\">$1</a>";

    private static final Pattern TWITTER_TWEETS_REGEX = Pattern.compile("(^| )@([a-zA-Z0-9_]+)",
            Pattern.CASE_INSENSITIVE);

    private static final String TWITTER_TWEETS_REPLACE = "$1<a target=\"new\" href=\"http://www.twitter.com/$2/\">@$2</a>";

    private static final Pattern TWITTER_HASHTAG_REGEX = Pattern.compile("(^| )#([a-zA-Z0-9_]+)",
            Pattern.CASE_INSENSITIVE);

    public static class ActivateTwitterLinksFormatter extends BaseFormatter {

        public ActivateTwitterLinksFormatter() {
            super("activate-twitter-links", false);
        }

        @Override
        public JsonNode apply(Context ctx, Arguments args, JsonNode node) throws CodeExecuteException {
            String text = node.asText();
            text = TWITTER_LINKS_REGEX.matcher(text).replaceAll(TWITTER_LINKS_REPLACE);
            text = TWITTER_TWEETS_REGEX.matcher(text).replaceAll(TWITTER_TWEETS_REPLACE);
            Matcher matcher = TWITTER_HASHTAG_REGEX.matcher(text);

            // Hate using StringBuffer, but see Sun bug 5066679
            StringBuffer buf = new StringBuffer();
            while (matcher.find()) {
                matcher.appendReplacement(buf, "<a target=\"new\" href=\"http://www.twitter.com/search/"
                        + GeneralUtils.urlEncode(matcher.group(2)) + "\">" + matcher.group(2) + "</a>");
            }
            matcher.appendTail(buf);
            return ctx.buildNode(buf.toString());
        }
    }

    public static class CommentsFormatter extends BaseFormatter {

        private Instruction template;

        public CommentsFormatter() {
            super("comments", false);
        }

        @Override
        public void initialize(Compiler compiler) throws CodeException {
            String source = loadResource(SocialFormatters.class, "comments.html");
            this.template = compiler.compile(source).code();
        }

        @Override
        public JsonNode apply(Context ctx, Arguments args, JsonNode item) throws CodeExecuteException {
            return executeTemplate(ctx, template, item, false);
        }
    }

    private static void addCommentCount(JsonNode item, StringBuilder buf) {
        int count = item.path("publicCommentCount").asInt();
        if (count == 0) {
            buf.append("No");
        } else {
            buf.append(count);
        }
        buf.append(" Comment");
        if (count != 1) {
            buf.append("s");
        }
    }

    public static class CommentLinkFormatter extends BaseFormatter {

        private Instruction template;

        public CommentLinkFormatter() {
            super("comment-link", false);
        }

        @Override
        public void initialize(Compiler compiler) throws CodeException {
            String source = loadResource(SocialFormatters.class, "comment-link.html");
            this.template = compiler.compile(source).code();
        }

        @Override
        public JsonNode apply(Context ctx, Arguments args, JsonNode item) throws CodeExecuteException {
            return executeTemplate(ctx, template, item, false);
        }
    }

    public static class CommentCountFormatter extends BaseFormatter {

        public CommentCountFormatter() {
            super("comment-count", false);
        }

        @Override
        public JsonNode apply(Context ctx, Arguments args, JsonNode item) throws CodeExecuteException {
            StringBuilder buf = new StringBuilder();
            addCommentCount(item, buf);
            return ctx.buildNode(buf.toString());
        }
    }

    public static class GoogleCalendarUrlFormatter extends BaseFormatter {

        public GoogleCalendarUrlFormatter() {
            super("google-calendar-url", false);
        }

        @Override
        public JsonNode apply(Context ctx, Arguments args, JsonNode node) throws CodeExecuteException {
            StringBuilder buf = new StringBuilder();
            long start = node.path("startDate").asLong();
            long end = node.path("endDate").asLong();
            buf.append("http://www.google.com/calendar/event?action=TEMPLATE&text=");
            buf.append(GeneralUtils.urlEncode(node.path("title").asText()));
            buf.append("&dates=");
            PluginDateUtils.formatDate(Locale.US, CALENDAR_DATE_FORMAT, start, "UTC", buf);
            buf.append("/");
            PluginDateUtils.formatDate(Locale.US, CALENDAR_DATE_FORMAT, end, "UTC", buf);
            if (node.has("location")) {
                String location = getLocationString(node.get("location"));
                if (StringUtils.trimToNull(location) != null) {
                    buf.append("&location=").append(GeneralUtils.urlEncode(location));
                }
            }
            return ctx.buildNode(buf.toString());
        }
    }

    private static String getLocationString(JsonNode location) {
        StringBuilder sb = new StringBuilder();
        String addressLine1 = location.path("addressLine1").asText();
        String addressLine2 = location.path("addressLine2").asText();
        String addressCountry = location.path("addressCountry").asText();
        if (StringUtils.trimToNull(addressLine1) != null) {
            sb.append(addressLine1);
        }
        if (StringUtils.trimToNull(addressLine2) != null) {
            if (sb.length() > 0) {
                sb.append(", ");
            }
            sb.append(addressLine2);
        }
        if (StringUtils.trimToNull(addressCountry) != null) {
            if (sb.length() > 0) {
                sb.append(", ");
            }
            sb.append(addressCountry);
        }
        return sb.toString();
    }

    public static class LikeButtonFormatter extends BaseFormatter {

        private Instruction template;

        public LikeButtonFormatter() {
            super("like-button", false);
        }

        @Override
        public void initialize(Compiler compiler) throws CodeException {
            String source = loadResource(SocialFormatters.class, "like-button.html");
            this.template = compiler.compile(source).code();
        }

        @Override
        public JsonNode apply(Context ctx, Arguments args, JsonNode item) throws CodeExecuteException {
            return executeTemplate(ctx, template, item, false);
        }
    }

    public static class SocialButtonFormatter extends BaseFormatter {

        public SocialButtonFormatter() {
            super("social-button", false);
        }

        @Override
        public JsonNode apply(Context ctx, Arguments args, JsonNode node) throws CodeExecuteException {
            JsonNode website = ctx.resolve("website");
            StringBuilder buf = new StringBuilder();
            PlatformUtils.makeSocialButton(website, node, false, buf);
            return ctx.buildNode(buf.toString());
        }
    }

    public static class SocialButtonInlineFormatter extends BaseFormatter {

        public SocialButtonInlineFormatter() {
            super("social-button-inline", false);
        }

        @Override
        public JsonNode apply(Context ctx, Arguments args, JsonNode node) throws CodeExecuteException {
            JsonNode website = ctx.resolve("website");
            StringBuilder buf = new StringBuilder();
            PlatformUtils.makeSocialButton(website, node, true, buf);
            return ctx.buildNode(buf.toString());
        }
    }

    public static class TwitterFollowButtonFormatter extends BaseFormatter {

        public TwitterFollowButtonFormatter() {
            super("twitter-follow-button", false);
        }

        @Override
        public JsonNode apply(Context ctx, Arguments args, JsonNode account) throws CodeExecuteException {
            StringBuilder buf = new StringBuilder();
            String userName = account.path("userName").asText();
            if (userName.equals("")) {
                String profileUrl = account.path("profileUrl").asText();
                String[] parts = StringUtils.split(profileUrl, '/');
                userName = parts[parts.length - 1];
            }
            buf.append("<script>Y.use('squarespace-follow-buttons', function(Y) { ");
            buf.append("Y.on('domready', function() { Y.Squarespace.FollowButtonUtils.renderAll(); }); });");
            buf.append("</script><div class=\"squarespace-follow-button\" data-username=\"");
            buf.append(userName);
            buf.append("\"></div>");
            return ctx.buildNode(buf.toString());
        }
    }

}