Package com.notnoop.apns.internal

Source Code of com.notnoop.apns.internal.Utilities

/*
* Copyright 2009, Mahmood Ali.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
*   * Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*   * Redistributions in binary form must reproduce the above
*     copyright notice, this list of conditions and the following disclaimer
*     in the documentation and/or other materials provided with the
*     distribution.
*   * Neither the name of Mahmood Ali. nor the names of its
*     contributors may be used to endorse or promote products derived from
*     this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.notnoop.apns.internal;

import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.security.KeyStore;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.notnoop.exceptions.InvalidSSLConfig;
import com.notnoop.exceptions.NetworkIOException;

public class Utilities {
    private static Logger logger = LoggerFactory.getLogger(Utilities.class);

    public static final String SANDBOX_GATEWAY_HOST = "gateway.sandbox.push.apple.com";
    public static final int SANDBOX_GATEWAY_PORT = 2195;

    public static final String SANDBOX_FEEDBACK_HOST = "feedback.sandbox.push.apple.com";
    public static final int SANDBOX_FEEDBACK_PORT = 2196;

    public static final String PRODUCTION_GATEWAY_HOST = "gateway.push.apple.com";
    public static final int PRODUCTION_GATEWAY_PORT = 2195;

    public static final String PRODUCTION_FEEDBACK_HOST = "feedback.push.apple.com";
    public static final int PRODUCTION_FEEDBACK_PORT = 2196;

    public static final int MAX_PAYLOAD_LENGTH = 256;


    public static SSLSocketFactory newSSLSocketFactory(InputStream cert, String password,
         String ksType, String ksAlgorithm) throws InvalidSSLConfig {
        SSLContext context = newSSLContext(cert, password, ksType, ksAlgorithm);
        return context.getSocketFactory();
    }

    public static SSLContext newSSLContext(InputStream cert, String password,
         String ksType, String ksAlgorithm) throws InvalidSSLConfig {
        try {
            KeyStore ks = KeyStore.getInstance(ksType);
            ks.load(cert, password.toCharArray());

            // Get a KeyManager and initialize it
            KeyManagerFactory kmf = KeyManagerFactory.getInstance(ksAlgorithm);
            kmf.init(ks, password.toCharArray());

            // Get a TrustManagerFactory and init with KeyStore
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(ksAlgorithm);
            tmf.init(ks);

            // Get the SSLContext to help create SSLSocketFactory
            SSLContext sslc = SSLContext.getInstance("TLS");
            sslc.init(kmf.getKeyManagers(), null, null);
            return sslc;
        } catch (Exception e) {
            throw new InvalidSSLConfig(e);
        }
    }

    private static final Pattern pattern = Pattern.compile("[ -]");
    public static byte[] decodeHex(String deviceToken) {
        String hex = pattern.matcher(deviceToken).replaceAll("");

        byte[] bts = new byte[hex.length() / 2];
        for (int i = 0; i < bts.length; i++) {
            bts[i] = (byte) (charval(hex.charAt(2*i)) * 16 + charval(hex.charAt(2*i + 1)));
        }
        return bts;
    }

    private static int charval(char a) {
        if ('0' <= a && a <= '9')
            return (a - '0');
        else if ('a' <= a && a <= 'f')
            return (a - 'a') + 10;
        else if ('A' <= a && a <= 'F')
            return (a - 'A') + 10;
        else
            throw new RuntimeException("Invalid hex character: " + a);
    }

    private static final char base[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

    public static String encodeHex(byte[] bytes) {
        char[] chars = new char[bytes.length * 2];

        for (int i = 0; i < bytes.length; ++i) {
            int b = ((int)bytes[i]) & 0xFF;
            chars[2 * i] = base[b >>> 4];
            chars[2 * i + 1] = base[b & 0xF];
        }

        return new String(chars);
    }

    public static byte[] toUTF8Bytes(String s) {
        try {
            return s.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    public static byte[] marshall(byte command, byte[] deviceToken, byte[] payload) {
        ByteArrayOutputStream boas = new ByteArrayOutputStream();
        DataOutputStream dos = new DataOutputStream(boas);

        try {
            dos.writeByte(command);
            dos.writeShort(deviceToken.length);
            dos.write(deviceToken);
            dos.writeShort(payload.length);
            dos.write(payload);
            return boas.toByteArray();
        } catch (IOException e) {
            throw new AssertionError();
        }
    }

    public static byte[] marshallEnhanced(byte command, int identifier,
            int expiryTime, byte[] deviceToken, byte[] payload) {
        ByteArrayOutputStream boas = new ByteArrayOutputStream();
        DataOutputStream dos = new DataOutputStream(boas);

        try {
            dos.writeByte(command);
            dos.writeInt(identifier);
            dos.writeInt(expiryTime);
            dos.writeShort(deviceToken.length);
            dos.write(deviceToken);
            dos.writeShort(payload.length);
            dos.write(payload);
            return boas.toByteArray();
        } catch (IOException e) {
            throw new AssertionError();
        }
    }

    public static Map<byte[], Integer> parseFeedbackStreamRaw(InputStream in) {
        Map<byte[], Integer> result = new HashMap<byte[], Integer>();

        DataInputStream data = new DataInputStream(in);

        while (true) {
            try {
                int time = data.readInt();
                int dtLength = data.readUnsignedShort();
                byte[] deviceToken = new byte[dtLength];
                data.readFully(deviceToken);

                result.put(deviceToken, time);
            } catch (EOFException e) {
                break;
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        return result;
    }

    public static Map<String, Date> parseFeedbackStream(InputStream in) {
        Map<String, Date> result = new HashMap<String, Date>();

        Map<byte[], Integer> raw = parseFeedbackStreamRaw(in);
        for (Map.Entry<byte[], Integer> entry : raw.entrySet()) {
            byte[] dtArray = entry.getKey();
            int time = entry.getValue(); // in seconds

            Date date = new Date(time * 1000L);    // in ms
            String dtString = encodeHex(dtArray);
            result.put(dtString, date);
        }

        return result;
    }

    public static void close(Closeable closeable) {
        try {
            if (closeable != null) {
                closeable.close();
            }
        } catch (IOException e) {
            logger.debug("error while closing resource", e);
        }
    }

    public static void close(Socket closeable) {
        try {
            if (closeable != null) {
                closeable.close();
            }
        } catch (IOException e) {
            logger.debug("error while closing socket", e);
        }
    }

    public static void sleep(int delay) {
        try {
            Thread.sleep(delay);
        } catch (InterruptedException e1) {}
    }

    public static byte[] copyOf(byte[] bytes) {
        byte[] copy = new byte[bytes.length];
        System.arraycopy(bytes, 0, copy, 0, bytes.length);
        return copy;
    }

    public static byte[] copyOfRange(byte[] original, int from, int to) {
        int newLength = to - from;
        if (newLength < 0)
            throw new IllegalArgumentException(from + " > " + to);
        byte[] copy = new byte[newLength];
        System.arraycopy(original, from, copy, 0,
                Math.min(original.length - from, newLength));
        return copy;
    }

    public static void wrapAndThrowAsRuntimeException(Exception e) throws NetworkIOException {
        if (e instanceof IOException)
            throw new NetworkIOException((IOException)e);
        else if (e instanceof NetworkIOException)
            throw (NetworkIOException)e;
        // unknown errors
        else if (e instanceof RuntimeException)
            throw (RuntimeException)e;
        else
            throw new RuntimeException(e);
    }

    public static int parseBytes(int b1, int b2, int b3, int b4) {
        return  ((b1 << 3 * 8) & 0xFF000000)
              | ((b2 << 2 * 8) & 0x00FF0000)
              | ((b3 << 1 * 8) & 0x0000FF00)
              | ((b4 << 0 * 8) & 0x000000FF);
    }
}
TOP

Related Classes of com.notnoop.apns.internal.Utilities

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.