com.kakao.kakaolink.KakaoTalkLinkMessageBuilder.java Source code

Java tutorial

Introduction

Here is the source code for com.kakao.kakaolink.KakaoTalkLinkMessageBuilder.java

Source

/**
 * Copyright 2014 Daum Kakao Corp.
 *
 * Redistribution and modification in source or binary forms are not permitted without specific prior written permission.
 *
 * 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.kakao.kakaolink;

import android.text.TextUtils;

import com.kakao.kakaolink.internal.Action;
import com.kakao.kakaolink.internal.KakaoTalkLinkProtocol;
import com.kakao.kakaolink.internal.LinkObject;
import com.kakao.kakaolink.internal.LinkObject.DISPLAY_TYPE;
import com.kakao.util.KakaoParameterException;
import com.kakao.util.helper.log.Logger;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 *   ?   Builder?.
 * ? ?  ? content .
 */
public class KakaoTalkLinkMessageBuilder {
    private final String appKey;
    private final String appVer;
    private final JSONObject extra;

    private final AtomicInteger textType;
    private final AtomicInteger imageType;
    private final AtomicInteger buttonType;
    private final AtomicInteger linkType;

    private final List<LinkObject> linkObjList;

    private boolean forwardable = false;

    KakaoTalkLinkMessageBuilder(final String appKey, final String appVer, final JSONObject extra) {
        this.appKey = appKey;
        this.appVer = appVer;
        this.extra = extra;

        this.textType = new AtomicInteger(0);
        this.imageType = new AtomicInteger(0);
        this.buttonType = new AtomicInteger(0);
        this.linkType = new AtomicInteger(0);

        this.linkObjList = new ArrayList<LinkObject>();
    }

    public KakaoTalkLinkMessageBuilder addExtra(final String key, final String value)
            throws KakaoParameterException {
        if (TextUtils.isEmpty(key) || TextUtils.isEmpty(value))
            throw new KakaoParameterException(KakaoParameterException.ERROR_CODE.CORE_PARAMETER_MISSING,
                    "extra key or value should not be null value.");

        try {
            extra.put(key, value);
        } catch (JSONException e) {
            Logger.w(e);
        }
        return this;
    }

    public KakaoTalkLinkMessageBuilder addExtra(final String key, final JSONObject value)
            throws KakaoParameterException {
        if (TextUtils.isEmpty(key) || value == null)
            throw new KakaoParameterException(KakaoParameterException.ERROR_CODE.CORE_PARAMETER_MISSING,
                    "extra key or value should not be null value.");

        try {
            extra.put(key, value);
        } catch (JSONException e) {
            Logger.w(e);
        }
        return this;
    }

    /**
     * ?  . ? ?  1000? ?.
     *
     * @param text  
     * @return   ?   Builder.
     * @throws KakaoParameterException ? ? ??  ??   ?.
     */
    public KakaoTalkLinkMessageBuilder addText(final String text) throws KakaoParameterException {
        return addText(text, DISPLAY_TYPE.BOTH);
    }

    /**
     * ?  . ? ?  1000? ?.
     *
     * @param text  
     * @param displayType object ? display  .(Permission?  ? ? .)
     * @return   ?   Builder.
     * @throws KakaoParameterException ? ? ??  ??   ?.
     */
    public KakaoTalkLinkMessageBuilder addText(final String text, final DISPLAY_TYPE displayType)
            throws KakaoParameterException {
        if (textType.getAndIncrement() == 1)
            throw new KakaoParameterException(KakaoParameterException.ERROR_CODE.DUPLICATE_OBJECTS_USED,
                    "textType already added. each type can be added once, at most.");

        final LinkObject textLink = LinkObject.newText(text, displayType);
        linkObjList.add(textLink);
        return this;
    }

    /**
     * ? ? .  70px * 70px ? ? ? , ? 500kb ? ? ? ?? ? ? url? ?? .
     *
     * @param src     ? ??  url
     * @param width   ??  ?
     * @param height  ??  ?
     * @return   ?   Builder.
     * @throws KakaoParameterException ? ? ??  ??   ?.
     */
    public KakaoTalkLinkMessageBuilder addImage(final String src, final int width, final int height)
            throws KakaoParameterException {
        return addImage(src, width, height, DISPLAY_TYPE.BOTH);
    }

    /**
     * ? ? .  70px * 70px ? ? ? , ? 500kb ? ? ? ?? ? ? url? ?? .
     *
     * @param src     ? ??  url
     * @param width   ??  ?
     * @param height  ??  ?
     * @param displayType object ? display  .(Permission?  ? ? .)
     * @return   ?   Builder.
     * @throws KakaoParameterException ? ? ??  ??   ?.
     */
    public KakaoTalkLinkMessageBuilder addImage(final String src, final int width, final int height,
            final DISPLAY_TYPE displayType) throws KakaoParameterException {
        if (imageType.getAndIncrement() == 1)
            throw new KakaoParameterException(KakaoParameterException.ERROR_CODE.DUPLICATE_OBJECTS_USED,
                    "imageType already added. each type can be added once, at most.");

        final LinkObject imageLink = LinkObject.newImage(src, width, height, displayType);
        linkObjList.add(imageLink);
        return this;
    }

    /**
     *   ? ? .
     *  ? kakao[appkey]://kakaolink ??.
     *  ?  url? append parameter   {@link #addAppButton(String, com.kakao.kakaolink.internal.Action)}? .
     * @param text ? ? ?
     * @return   ?   Builder.
     * @throws KakaoParameterException ?  ??  ??   ?.
     */
    public KakaoTalkLinkMessageBuilder addAppButton(final String text) throws KakaoParameterException {
        return addAppButton(text, Action.newActionApp(null, null));
    }

    /**
     *   ? ? .
     *  ?  url? append parameter   .
     *  ? kakao[appkey]://akaolink ?? {@link #addAppButton(String)} .
     * @param text      ? ? ?
     * @param appAction app  url? append parameter os, device 
     * @return   ?   Builder.
     * @throws KakaoParameterException ?  ??  ??   ?.
     */
    public KakaoTalkLinkMessageBuilder addAppButton(final String text, final Action appAction)
            throws KakaoParameterException {
        return addAppButton(text, appAction, DISPLAY_TYPE.BOTH);
    }

    /**
     *   ? ? .
     *  ?  url? append parameter   .
     *  ? kakao[appkey]://akaolink ?? {@link #addAppButton(String)} .
     * @param text      ? ? ?
     * @param appAction app  url? append parameter os, device 
     * @param displayType object ? display  .(Permission?  ? ? .)
     * @return   ?   Builder.
     * @throws KakaoParameterException ?  ??  ??   ?.
     */
    public KakaoTalkLinkMessageBuilder addAppButton(final String text, final Action appAction,
            final DISPLAY_TYPE displayType) throws KakaoParameterException {
        if (buttonType.getAndIncrement() == 1)
            throw new KakaoParameterException(KakaoParameterException.ERROR_CODE.DUPLICATE_OBJECTS_USED,
                    "buttonType already added. each type can be added once, at most.");

        final LinkObject appButton = LinkObject.newButton(text, appAction, displayType);
        linkObjList.add(appButton);
        return this;
    }

    /**
     * ? ? ? ??  ? ? .
     * ? ? ??? path, parameter? ?   url  ?  {@link #addWebButton(String, String)}? .
     * @param text ? ? ?
     * @return   ?   Builder.
     * @throws KakaoParameterException  ?  ??  ??   ?.
     */
    public KakaoTalkLinkMessageBuilder addWebButton(final String text) throws KakaoParameterException {
        return addWebButton(text, null);
    }

    /**
     * ?  ? ? .
     * ? ? ? ??  ?  {@link #addWebButton(String)}? .
     * @param text ? ? ?
     * @param url  ? ? ??? path, parameter? ?   url
     * @return   ?   Builder.
     * @throws KakaoParameterException ?  ??  ??   ?.
     */
    public KakaoTalkLinkMessageBuilder addWebButton(final String text, final String url)
            throws KakaoParameterException {
        return addWebButton(text, url, DISPLAY_TYPE.BOTH);
    }

    /**
     * ?  ? ? .
     * ? ? ? ??  ?  {@link #addWebButton(String)}? .
     * @param text ? ? ?
     * @param url  ? ? ??? path, parameter? ?   url
     * @param displayType object ? display  .(Permission?  ? ? .)
     * @return   ?   Builder.
     * @throws KakaoParameterException ?  ??  ??   ?.
     */
    public KakaoTalkLinkMessageBuilder addWebButton(final String text, final String url,
            final DISPLAY_TYPE displayType) throws KakaoParameterException {
        if (buttonType.getAndIncrement() == 1)
            throw new KakaoParameterException(KakaoParameterException.ERROR_CODE.DUPLICATE_OBJECTS_USED,
                    "buttonType already added. each type can be added once, at most.");

        final Action webAction = Action.newActionWeb(url);
        final LinkObject webButton = LinkObject.newButton(text, webAction, displayType);
        linkObjList.add(webButton);
        return this;
    }

    /**
     *   ?? ? .
     * ?? ? kakao[appkey]://exec ??.
     *  url? append parameter   {@link #addAppLink(String, Action, DISPLAY_TYPE)}  .
     * @param text ???  ?
     * @return   ?   Builder.
     * @throws KakaoParameterException ? ?? ??  ??   ?.
     */
    public KakaoTalkLinkMessageBuilder addAppLink(final String text) throws KakaoParameterException {
        return addAppLink(text, Action.newActionApp(null, null), DISPLAY_TYPE.BOTH);
    }

    /**
     *   ?? ? .
     * ?? ?   url? append parameter   .
     * ?? ? kakao[appkey]://exec ?? {@link #addAppLink(String)} .
     * @param text      ???  ?
     * @param appAction   url? append parameter os, device 
     * @return   ?   Builder.
     * @throws KakaoParameterException  ? ?? ??  ??   ?.
     */
    public KakaoTalkLinkMessageBuilder addAppLink(final String text, final Action appAction)
            throws KakaoParameterException {
        return addAppLink(text, appAction, DISPLAY_TYPE.BOTH);
    }

    /**
     *   ?? ? .
     * ?? ?   url? append parameter   .
     * ?? ? kakao[appkey]://exec ?? {@link #addAppLink(String)} .
     * @param text      ???  ?
     * @param appAction   url? append parameter os, device 
     * @param displayType object ? display  .(Permission?  ? ? .)
     * @return   ?   Builder.
     * @throws KakaoParameterException  ? ?? ??  ??   ?.
     */
    public KakaoTalkLinkMessageBuilder addAppLink(final String text, final Action appAction,
            final DISPLAY_TYPE displayType) throws KakaoParameterException {
        if (linkType.getAndIncrement() == 1)
            throw new KakaoParameterException(KakaoParameterException.ERROR_CODE.DUPLICATE_OBJECTS_USED,
                    "linkType already added. each type can be added once, at most.");

        final LinkObject appLink = LinkObject.newLink(text, appAction, displayType);
        linkObjList.add(appLink);
        return this;
    }

    /**
     * ? ? ? ??  ?? ? .
     * ? ? ??? path, parameter? ?   url  ???  {@link #addWebLink(String, String)}? .
     * @param text ???  ?
     * @return   ?   Builder.
     * @throws KakaoParameterException ? ?? ??  ??   ?.
     */
    public KakaoTalkLinkMessageBuilder addWebLink(final String text) throws KakaoParameterException {
        addWebLink(text, null);
        return this;
    }

    /**
     * ?  ?? ? .
     * ? ? ? ??  ???  {@link #addWebLink(String)}? .
     * @param text ???  ?
     * @param url  ? ? ??? path, parameter? ?   url
     * @return   ?   Builder.
     * @throws KakaoParameterException ? ?? ??  ??   ?.
     */
    public KakaoTalkLinkMessageBuilder addWebLink(final String text, final String url)
            throws KakaoParameterException {
        return addWebLink(text, url, DISPLAY_TYPE.BOTH);
    }

    /**
     * ?  ?? ? .
     * ? ? ? ??  ???  {@link #addWebLink(String)}? .
     * @param text ???  ?
     * @param url  ? ? ??? path, parameter? ?   url
     * @param displayType object ? display  .(Permission?  ? ? .)
     * @return   ?   Builder.
     * @throws KakaoParameterException ? ?? ??  ??   ?.
     */
    public KakaoTalkLinkMessageBuilder addWebLink(final String text, final String url,
            final DISPLAY_TYPE displayType) throws KakaoParameterException {
        if (linkType.getAndIncrement() == 1)
            throw new KakaoParameterException(KakaoParameterException.ERROR_CODE.DUPLICATE_OBJECTS_USED,
                    "linkType already added. each type can be added once, at most.");

        final Action webAction = Action.newActionWeb(url);
        final LinkObject webLink = LinkObject.newLink(text, webAction, displayType);

        linkObjList.add(webLink);
        return this;
    }

    /**
     * ? ? ? ??  ?? ? .
     * ? ? ??? path, parameter? ?   url  ???  {@link #addInWebLink(String, String)}? .
     * @param text ???  ?
     * @return   ?   Builder.
     * @throws KakaoParameterException ? ?? ??  ??   ?.
     */
    public KakaoTalkLinkMessageBuilder addInWebLink(final String text) throws KakaoParameterException {
        return addInWebLink(text, null);
    }

    /**
     * ?  ?? ? .
     * ? ? ? ??  ???  {@link #addInWebLink(String)}? .
     * @param text ???  ?
     * @param url  ? ? ??? path, parameter? ?   url
     * @return   ?   Builder.
     * @throws KakaoParameterException ? ?? ??  ??   ?.
     */
    public KakaoTalkLinkMessageBuilder addInWebLink(final String text, final String url)
            throws KakaoParameterException {
        return addInWebLink(text, null, DISPLAY_TYPE.BOTH);
    }

    /**
     * ?  ?? ? .
     * ? ? ? ??  ???  {@link #addInWebLink(String)}? .
     * @param text ???  ?
     * @param url  ? ? ??? path, parameter? ?   url
     * @return   ?   Builder.
     * @throws KakaoParameterException ? ?? ??  ??   ?.
     */
    public KakaoTalkLinkMessageBuilder addInWebLink(final String text, final String url,
            final DISPLAY_TYPE displayType) throws KakaoParameterException {
        if (linkType.getAndIncrement() == 1)
            throw new KakaoParameterException(KakaoParameterException.ERROR_CODE.DUPLICATE_OBJECTS_USED,
                    "linkType already added. each type can be added once, at most.");

        final Action inwebAction = Action.newActionInWeb(url);
        final LinkObject webLink = LinkObject.newLink(text, inwebAction, displayType);

        linkObjList.add(webLink);
        return this;
    }

    /**
     * ? ??  ,   ?  .
     * @param forwardable
     * @return   ?   Builder.
     */
    public KakaoTalkLinkMessageBuilder setForwardable(boolean forwardable) {
        this.forwardable = forwardable;
        return this;
    }

    /**
     *  ?   ?  ?  .
     * @return  ?  
     * @throws KakaoParameterException ?     ?.
     */
    public String build() throws KakaoParameterException {
        try {
            if (linkObjList.isEmpty())
                throw new KakaoParameterException(KakaoParameterException.ERROR_CODE.CORE_PARAMETER_MISSING,
                        "call addAppLink or addWebLink or addAppButton or addWebButton or addText or addImage before calling build().");

            final StringBuilder talkLinkURL = new StringBuilder(KakaoTalkLinkProtocol.KAKAO_TALK_LINK_URL)
                    .append("?");
            talkLinkURL.append(KakaoTalkLinkProtocol.LINK_VER).append("=")
                    .append(URLEncoder.encode(KakaoTalkLinkProtocol.LINK_VERSION, KakaoTalkLinkProtocol.ENCODING))
                    .append("&");
            talkLinkURL.append(KakaoTalkLinkProtocol.API_VER).append("=")
                    .append(URLEncoder.encode(KakaoTalkLinkProtocol.API_VERSION, KakaoTalkLinkProtocol.ENCODING))
                    .append("&");
            talkLinkURL.append(KakaoTalkLinkProtocol.APP_KEY).append("=")
                    .append(URLEncoder.encode(appKey, KakaoTalkLinkProtocol.ENCODING)).append("&");
            talkLinkURL.append(KakaoTalkLinkProtocol.APP_VER).append("=")
                    .append(URLEncoder.encode(appVer, KakaoTalkLinkProtocol.ENCODING)).append("&");
            talkLinkURL.append(KakaoTalkLinkProtocol.FORWARDABLE).append("=")
                    .append(URLEncoder.encode(String.valueOf(forwardable), KakaoTalkLinkProtocol.ENCODING))
                    .append("&");
            talkLinkURL.append(KakaoTalkLinkProtocol.EXTRAS).append("=")
                    .append(URLEncoder.encode(extra.toString(), KakaoTalkLinkProtocol.ENCODING)).append("&");

            talkLinkURL.append(KakaoTalkLinkProtocol.OBJS).append("=");
            final JSONArray jsonArray = new JSONArray();
            for (LinkObject linkObject : linkObjList) {
                jsonArray.put(linkObject.createJSONObject());
            }

            Logger.d("====================================================================================");
            Logger.d("++ LINK_VERSION : " + KakaoTalkLinkProtocol.LINK_VERSION);
            Logger.d("++ API_VERSION : " + KakaoTalkLinkProtocol.API_VERSION);
            Logger.d("++ appKey : " + appKey);
            Logger.d("++ appVer : " + appVer);
            Logger.d("++  : " + extra);
            Logger.d("++ linkObjList = %s", jsonArray.toString());
            Logger.d("====================================================================================");
            final String encodedValue = URLEncoder.encode(jsonArray.toString(), KakaoTalkLinkProtocol.ENCODING);
            return talkLinkURL.append(encodedValue).toString();

        } catch (UnsupportedEncodingException e) {
            throw new KakaoParameterException(KakaoParameterException.ERROR_CODE.UNSUPPORTED_ENCODING, e);
        } catch (JSONException e) {
            throw new KakaoParameterException(KakaoParameterException.ERROR_CODE.JSON_PARSING_ERROR, e);
        }
    }
}