com.kku.apps.pricesearch.util.SignedHelper.java Source code

Java tutorial

Introduction

Here is the source code for com.kku.apps.pricesearch.util.SignedHelper.java

Source

/*
 * Copyright (C) 2012 kkurahar
 *
 * 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.kku.apps.pricesearch.util;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TimeZone;
import java.util.TreeMap;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

public class SignedHelper {
    private static final String SEPARATOR = "|";
    private static final String ENCODING = "UTF-8";
    private static final String ALGORITHM = "HmacSHA256";
    private static final String HTTPMETHOD = "GET";

    /**
     * ??l???B
     * 
     * @param secretKey
     *            API?B
     * @param url
     *            http://api.7netshopping.jp/ws/affiliate/[rest|soap]/[
     *            NGXg?bZ?[W] `URL?B
     * @param params
     *            NGXgp??[^(Signature?)?B
     * @return ??l?B
     * @throws Exception
     *             ??????O??B
     */
    public static String createSignatureValue(String secretKey, String url, Map<String, String> params)
            throws Exception {
        params.put("Timestamp", timestamp());
        String targetString = createTargetString(url, params);
        String sig = sign(secretKey, targetString);
        SortedMap<String, String> sortedParamMap = new TreeMap<String, String>(params);
        String canonicalQS = canonicalize(sortedParamMap);
        String rUrl = url + "?" + canonicalQS + "&Signature=" + sig;
        return rUrl;
    }

    private static String createTargetString(String url, Map<String, String> params) throws Exception {
        List<String> paramsList = createParamsList(params);

        StringBuilder sb = new StringBuilder();
        for (String keyAndValue : paramsList) {
            sb.append(SEPARATOR);
            sb.append(keyAndValue);
        }
        String parameters = sb.toString();

        String sourceString = String.format("%s%s%s%s", HTTPMETHOD, SEPARATOR, url, parameters);

        return percentEncodeRfc3986(sourceString);
    }

    private static List<String> createParamsList(Map<String, String> params) {
        List<String> paramsList = new ArrayList<String>(params.size());
        for (Map.Entry<String, String> map : params.entrySet()) {
            paramsList.add(String.format("%s=%s", map.getKey(), map.getValue()));
        }
        Collections.sort(paramsList);
        return paramsList;
    }

    private static String sign(String apiSecretKey, String sourceString) throws Exception {
        SecretKeySpec secretKeySpec = new SecretKeySpec(apiSecretKey.getBytes(ENCODING), ALGORITHM);
        Mac mac = Mac.getInstance(ALGORITHM);
        mac.init(secretKeySpec);
        byte[] data = mac.doFinal(sourceString.getBytes(ENCODING));
        Base64 encoder = new Base64();
        String signature = new String(encoder.encode(data));
        return signature;
    }

    private static String percentEncodeRfc3986(String s) {
        String out;
        try {
            out = URLEncoder.encode(s, ENCODING).replace("+", "%20").replace("*", "%2A").replace("%7E", "~");
        } catch (UnsupportedEncodingException e) {
            out = s;
        }
        return out;
    }

    private static String timestamp() {
        String timestamp = null;
        Calendar cal = Calendar.getInstance();
        DateFormat dfm = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        dfm.setTimeZone(TimeZone.getTimeZone("GMT"));
        timestamp = dfm.format(cal.getTime());
        return timestamp;
    }

    private static String canonicalize(SortedMap<String, String> sortedParamMap) {
        if (sortedParamMap.isEmpty()) {
            return "";
        }

        StringBuffer buffer = new StringBuffer();
        Iterator<Map.Entry<String, String>> iter = sortedParamMap.entrySet().iterator();

        while (iter.hasNext()) {
            Map.Entry<String, String> kvpair = iter.next();
            buffer.append(percentEncodeRfc3986(kvpair.getKey()));
            buffer.append("=");
            buffer.append(percentEncodeRfc3986(kvpair.getValue()));
            if (iter.hasNext()) {
                buffer.append("&");
            }
        }
        String cannoical = buffer.toString();
        return cannoical;
    }

}