Java tutorial
/* * Copyright 2013 DiscoveryBay 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.dbay.apns4j.tools; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.Date; import java.util.Enumeration; import java.util.List; import javax.net.SocketFactory; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory; import javax.security.cert.CertificateExpiredException; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.time.DateFormatUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.dbay.apns4j.model.Command; import com.dbay.apns4j.model.FrameItem; /** * @author RamosLi * */ public abstract class ApnsTools { private final static Logger LOG = LoggerFactory.getLogger(ApnsTools.class); public final static byte[] generateData(List<FrameItem> list) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream os = new DataOutputStream(bos); int frameLength = 0; for (FrameItem item : list) { // itemId length = 1, itemDataLength = 2 frameLength += 1 + 2 + item.getItemLength(); } try { os.writeByte(Command.SEND_V2); os.writeInt(frameLength); for (FrameItem item : list) { os.writeByte(item.getItemId()); os.writeShort(item.getItemLength()); os.write(item.getItemData()); } return bos.toByteArray(); } catch (IOException e) { e.printStackTrace(); } throw new RuntimeException(); } @Deprecated public final static byte[] generateData(int id, int expire, byte[] token, byte[] payload) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream os = new DataOutputStream(bos); try { os.writeByte(Command.SEND); os.writeInt(id); os.writeInt(expire); os.writeShort(token.length); os.write(token); os.writeShort(payload.length); os.write(payload); os.flush(); return bos.toByteArray(); } catch (IOException e) { e.printStackTrace(); } throw new RuntimeException(); } private final static String[] hexArr = new String[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" }; public final static String encodeHex(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (byte b : bytes) { sb.append(hexArr[(b >> 4) & 0x0F]); sb.append(hexArr[b & 0x0F]); } return sb.toString(); } public final static byte[] decodeHex(String hex) { byte[] bytes = new byte[hex.length() / 2]; for (int i = 0; i < bytes.length; i++) { bytes[i] = (byte) ((hexCharIndex(hex.charAt(2 * i)) << 4) | hexCharIndex(hex.charAt(2 * i + 1))); } return bytes; } /** * @param hex * @return 0---15 */ private final static int hexCharIndex(char hex) { int index = 0; if (hex >= '0' && hex <= '9') { index = hex - '0'; } else if (hex >= 'a' && hex <= 'f') { index = hex - 'a' + 10; } else if (hex >= 'A' && hex <= 'F') { index = hex - 'A' + 10; } else { throw new IllegalArgumentException("Invalid hex char. " + hex); } return index; } public final static int parse4ByteInt(byte b1, byte b2, byte b3, byte b4) { return ((b1 << 24) & 0xFF000000) | ((b2 << 16) & 0x00FF0000) | ((b3 << 8) & 0x0000FF00) | (b4 & 0x000000FF); } public final static SocketFactory createSocketFactory(InputStream keyStore, String password, String keystoreType, String algorithm, String protocol) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableKeyException, KeyManagementException, CertificateExpiredException { char[] pwdChars = password.toCharArray(); KeyStore ks = KeyStore.getInstance(keystoreType); ks.load(keyStore, pwdChars); // ?? Enumeration<String> enums = ks.aliases(); String alias = ""; if (enums.hasMoreElements()) { alias = enums.nextElement(); } if (StringUtils.isNotEmpty(alias)) { X509Certificate certificate = (X509Certificate) ks.getCertificate(alias); if (null != certificate) { String type = certificate.getType(); int ver = certificate.getVersion(); String name = certificate.getSubjectDN().getName(); String serialNumber = certificate.getSerialNumber().toString(16); String issuerDN = certificate.getIssuerDN().getName(); String sigAlgName = certificate.getSigAlgName(); String publicAlgorithm = certificate.getPublicKey().getAlgorithm(); Date before = certificate.getNotBefore(); Date after = certificate.getNotAfter(); String beforeStr = DateFormatUtils.format(before, "yyyy-MM-dd HH:mm:ss"); String afterStr = DateFormatUtils.format(after, "yyyy-MM-dd HH:mm:ss"); // ?? long expire = DateUtil.getNumberOfDaysBetween(new Date(), after); if (expire <= 0) { if (LOG.isErrorEnabled()) { LOG.error( "?[{}], [{}], ?[{}], ??[{}], ?[{}], ??[{}], [{}], [{}][{}], ?[{}]", name, type, ver, serialNumber, issuerDN, sigAlgName, publicAlgorithm, beforeStr, afterStr, Math.abs(expire)); } throw new CertificateExpiredException("??[" + Math.abs(expire) + "]"); } if (LOG.isInfoEnabled()) { LOG.info( "?[{}], [{}], ?[{}], ??[{}], ?[{}], ??[{}], [{}], [{}][{}], ?[{}]?", name, type, ver, serialNumber, issuerDN, sigAlgName, publicAlgorithm, beforeStr, afterStr, expire); } } } KeyManagerFactory kf = KeyManagerFactory.getInstance(algorithm); kf.init(ks, pwdChars); TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm); tmf.init((KeyStore) null); SSLContext context = SSLContext.getInstance(protocol); context.init(kf.getKeyManagers(), tmf.getTrustManagers(), null); return context.getSocketFactory(); } // All data is specified in network order, that is big endian. public final static byte[] intToBytes(int num, int resultBytesCount) { byte[] ret = new byte[resultBytesCount]; for (int i = 0; i < resultBytesCount; i++) { ret[i] = (byte) ((num >> ((resultBytesCount - 1 - i) * 8)) & 0xFF); } return ret; } }