();
- if (payloadDevicePairs == null) return devices;
- PushNotificationManager pushManager = new PushNotificationManager();
- try {
- AppleNotificationServer server = new AppleNotificationServerBasicImpl(keystore, password, production);
- pushManager.initializeConnection(server);
- for (PayloadPerDevice ppd : payloadDevicePairs) {
- Device device = ppd.getDevice();
- Payload payload = ppd.getPayload();
- PushedNotification notification = pushManager.sendNotification(device, payload, false);
- devices.add(notification);
- }
- } catch (Exception e) {
- System.out.println("Error pushing notification(s):");
- e.printStackTrace();
- } finally {
- try {
- pushManager.stopConnection();
- } catch (Exception e) {
- }
- }
- return devices;
- }
-
-
- /**
- * Retrieve a list of devices that should be removed from future notification lists.
- *
- * Devices in this list are ones that you previously tried to push a notification to,
- * but to which Apple could not actually deliver because the device user has either
- * opted out of notifications, has uninstalled your application, or some other conditions.
- *
- * Important: Apple's Feedback Service always resets its list of inactive devices
- * after each time you contact it. Calling this method twice will not return the same
- * list of devices!
- *
- * Please be aware that Apple does not specify precisely when a device will be listed
- * by the Feedback Service. More specifically, it is unlikely that the device will
- * be listed immediately if you uninstall the application during testing. It might
- * get listed after some number of notifications couldn't reach it, or some amount of
- * time has elapsed, or a combination of both.
- *
- * Further more, if you are using Apple's sandbox servers, the Feedback Service will
- * probably not list your device if you uninstalled your app and it was the last one
- * on your device that was configured to receive notifications from the sandbox.
- * See the library's wiki for more information.
- *
- * @param keystore a PKCS12 keystore provided by Apple (File, InputStream, byte[] or String for a file path)
- * @param password the keystore's password.
- * @param production true to use Apple's production servers, false to use the sandbox servers.
- * @return a list of devices that are inactive.
- */
- public static List feedback(Object keystore, String password, boolean production) {
- List devices = new Vector();
- try {
- FeedbackServiceManager feedbackManager = new FeedbackServiceManager();
- AppleFeedbackServer server = new AppleFeedbackServerBasicImpl(keystore, password, production);
- devices.addAll(feedbackManager.getDevices(server));
- } catch (Exception e) {
- System.out.println("Error pushing notification(s):");
- e.printStackTrace();
- }
- return devices;
- }
-
-}
diff --git a/javapns/src/main/java/javapns/communication/AppleServer.java b/javapns/src/main/java/javapns/communication/AppleServer.java
deleted file mode 100644
index b033d1f6d..000000000
--- a/javapns/src/main/java/javapns/communication/AppleServer.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package javapns.communication;
-
-import java.io.*;
-
-/**
- * Common interface of all classes representing a connection to any Apple server.
- * Use AppleNotificationServer and AppleFeedbackServer interfaces for specific connections.
- *
- * @author Sylvain Pedneault
- */
-public interface AppleServer {
-
- /**
- * Returns a stream to a keystore.
- * @return an InputStream
- */
- public InputStream getKeystoreStream();
-
-
- /**
- * Returns the keystore's password.
- * @return a password matching the keystore
- */
- public String getKeystorePassword();
-
- /**
- * Returns the format used to produce the keystore (typically PKCS12).
- * @return a valid keystore format identifier
- */
- public String getKeystoreType();
-
-}
diff --git a/javapns/src/main/java/javapns/communication/AppleServerBasicImpl.java b/javapns/src/main/java/javapns/communication/AppleServerBasicImpl.java
deleted file mode 100644
index fe3aa3ac4..000000000
--- a/javapns/src/main/java/javapns/communication/AppleServerBasicImpl.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package javapns.communication;
-
-import java.io.*;
-
-/**
- * A basic and abstract implementation of the AppleServer interface
- * intended to facilitate rapid deployment.
- *
- * @author Sylvain Pedneault
- */
-public abstract class AppleServerBasicImpl implements AppleServer {
-
- private final Object keystore;
- private final String password;
- private final String type;
-
-
- /**
- * Constructs a AppleServerBasicImpl object.
- *
- * @param keystore The keystore to use (can be a File, an InputStream, a String for a file path, or a byte[] array)
- * @param password The keystore's password
- * @param type The keystore type (typically PKCS12)
- * @throws FileNotFoundException
- */
- public AppleServerBasicImpl(Object keystore, String password, String type) throws FileNotFoundException {
- //this.input = KeystoreManager.streamKeystore(keystore);
- this.keystore = keystore;
- this.password = password;
- this.type = type;
- }
-
-
- public InputStream getKeystoreStream() {
- try {
- return KeystoreManager.streamKeystore(keystore);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- return null;
- }
- }
-
-
- public String getKeystorePassword() {
- return password;
- }
-
-
- public String getKeystoreType() {
- return type;
- }
-
-}
diff --git a/javapns/src/main/java/javapns/communication/ConnectionToAppleServer.java b/javapns/src/main/java/javapns/communication/ConnectionToAppleServer.java
deleted file mode 100644
index 85fbe41cc..000000000
--- a/javapns/src/main/java/javapns/communication/ConnectionToAppleServer.java
+++ /dev/null
@@ -1,250 +0,0 @@
-package javapns.communication;
-
-import java.io.*;
-import java.net.*;
-import java.security.*;
-import java.security.cert.*;
-
-import javax.net.ssl.*;
-
-import org.bouncycastle.jce.provider.*;
-import com.genexus.diagnostics.core.*;
-/**
- * Class representing an abstract connection to an Apple server
- *
- * Communication protocol differences between Notification and Feedback servers are
- * implemented in {@link javapns.notification.ConnectionToNotificationServer} and {@link javapns.feedback.ConnectionToFeedbackServer}.
- *
- * @author Sylvain Pedneault
- */
-public abstract class ConnectionToAppleServer {
-
- protected static final ILogger logger = LogManager.getLogger(ConnectionToAppleServer.class);
-
- /* The algorithm used by KeyManagerFactory */
- private static final String ALGORITHM = ((Security.getProperty("ssl.KeyManagerFactory.algorithm") == null) ? "sunx509" : Security.getProperty("ssl.KeyManagerFactory.algorithm"));
-
- /* The protocol used to create the SSLSocket */
- private static final String PROTOCOL = "TLS";
-
- /* PKCS12 */
- public static final String KEYSTORE_TYPE_PKCS12 = "PKCS12";
- /* JKS */
- public static final String KEYSTORE_TYPE_JKS = "JKS";
-
- static {
- Security.addProvider(new BouncyCastleProvider());
- }
-
- private KeyStore keyStore;
- private SSLSocketFactory socketFactory;
- private AppleServer server;
-
-
- /**
- * Builds a connection to an Apple server.
- *
- * @param server
- * @throws KeyStoreException
- * @throws NoSuchAlgorithmException
- * @throws CertificateException
- * @throws IOException
- * @throws Exception
- */
- public ConnectionToAppleServer(AppleServer server) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, Exception {
- this.server = server;
-
- this.keyStore = KeystoreManager.loadKeystore(server);
- }
-
-
- public AppleServer getServer() {
- return server;
- }
-
-
- public KeyStore getKeystore() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, Exception {
- return keyStore;
- // return KeystoreManager.loadKeystore(server);
- }
-
-
- public void setKeystore(KeyStore ks) {
- this.keyStore = ks;
- }
-
-
- /**
- * Generic SSLSocketFactory builder
- *
- * @param trustManagers
- * @return SSLSocketFactory
- * @throws Exception
- */
- protected SSLSocketFactory createSSLSocketFactoryWithTrustManagers(TrustManager[] trustManagers) throws Exception {
-
- logger.debug("Creating SSLSocketFactory");
- // Get a KeyManager and initialize it
- KeyStore keystore = getKeystore();
- KeyManagerFactory kmf = KeyManagerFactory.getInstance(ALGORITHM);
- try {
- char[] password = KeystoreManager.getKeystorePasswordForSSL(server);
- kmf.init(keystore, password);
- } catch (Exception e) {
- e = KeystoreManager.getSimplerSSLException(e);
- throw e;
- }
-
- // Get the SSLContext to help create SSLSocketFactory
- SSLContext sslc = SSLContext.getInstance(PROTOCOL);
- sslc.init(kmf.getKeyManagers(), trustManagers, null);
-
- return sslc.getSocketFactory();
- }
-
-
- public abstract String getServerHost();
-
-
- public abstract int getServerPort();
-
-
- /**
- * Return a SSLSocketFactory for creating sockets to communicate with Apple.
- *
- * @return SSLSocketFactory
- * @throws KeyStoreException
- * @throws NoSuchProviderException
- * @throws CertificateException
- * @throws NoSuchAlgorithmException
- * @throws IOException
- * @throws UnrecoverableKeyException
- * @throws KeyManagementException
- * @throws Exception
- */
- public SSLSocketFactory createSSLSocketFactory() throws KeyStoreException, NoSuchProviderException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableKeyException, KeyManagementException, Exception {
- return createSSLSocketFactoryWithTrustManagers(new TrustManager[] { new ServerTrustingTrustManager() });
- }
-
-
- public SSLSocketFactory getSSLSocketFactory() throws Exception {
- if (socketFactory == null) socketFactory = createSSLSocketFactory();
- return socketFactory;
- }
-
-
- /**
- * Create a SSLSocket which will be used to send data to Apple
- * @return the SSLSocket
- * @throws Exception
- * @throws FileNotFoundException
- */
- public SSLSocket getSSLSocket() throws Exception {
- SSLSocketFactory socketFactory = getSSLSocketFactory();
- logger.debug("Creating SSLSocket to " + getServerHost() + ":" + getServerPort());
-
- try {
- if (isProxySet()) {
- return tunnelThroughProxy(socketFactory);
- } else {
- return (SSLSocket) socketFactory.createSocket(getServerHost(), getServerPort());
- }
- } catch (Exception e) {
- throw e;
- }
- }
-
-
- private boolean isProxySet() {
- String httpsHost = System.getProperty("https.proxyHost");
- boolean isSet = httpsHost != null && httpsHost.length() > 0;
- return isSet;
- }
-
-
- private SSLSocket tunnelThroughProxy(SSLSocketFactory socketFactory) throws UnknownHostException, IOException {
- SSLSocket socket;
-
- // If a proxy was set, tunnel through the proxy to create the connection
- String tunnelHost = System.getProperty("https.proxyHost");
- Integer tunnelPort = Integer.getInteger("https.proxyPort").intValue();
-
- Socket tunnel = new Socket(tunnelHost, tunnelPort);
- doTunnelHandshake(tunnel, getServerHost(), getServerPort());
-
- /* overlay the tunnel socket with SSL */
- socket = (SSLSocket) socketFactory.createSocket(tunnel, getServerHost(), getServerPort(), true);
-
- /* register a callback for handshaking completion event */
- socket.addHandshakeCompletedListener(new HandshakeCompletedListener() {
- public void handshakeCompleted(HandshakeCompletedEvent event) {
- logger.debug("Handshake finished!");
- logger.debug("\t CipherSuite:" + event.getCipherSuite());
- logger.debug("\t SessionId " + event.getSession());
- logger.debug("\t PeerHost " + event.getSession().getPeerHost());
- }
- });
-
- return socket;
- }
-
-
- private void doTunnelHandshake(Socket tunnel, String host, int port) throws IOException {
-
- OutputStream out = tunnel.getOutputStream();
-
- String msg = "CONNECT " + host + ":" + port + " HTTP/1.0\n" + "User-Agent: BoardPad Server" + "\r\n\r\n";
- byte b[] = null;
- try { //We really do want ASCII7 -- the http protocol doesn't change with locale.
- b = msg.getBytes("ASCII7");
- } catch (UnsupportedEncodingException ignored) { //If ASCII7 isn't there, something serious is wrong, but Paranoia Is Good (tm)
- b = msg.getBytes();
- }
- out.write(b);
- out.flush();
-
- // We need to store the reply so we can create a detailed error message to the user.
- byte reply[] = new byte[200];
- int replyLen = 0;
- int newlinesSeen = 0;
- boolean headerDone = false; //Done on first newline
-
- InputStream in = tunnel.getInputStream();
-
- while (newlinesSeen < 2) {
- int i = in.read();
- if (i < 0) {
- throw new IOException("Unexpected EOF from proxy");
- }
- if (i == '\n') {
- headerDone = true;
- ++newlinesSeen;
- } else if (i != '\r') {
- newlinesSeen = 0;
- if (!headerDone && replyLen < reply.length) {
- reply[replyLen++] = (byte) i;
- }
- }
- }
-
- /*
- * Converting the byte array to a string is slightly wasteful
- * in the case where the connection was successful, but it's
- * insignificant compared to the network overhead.
- */
- String replyStr;
- try {
- replyStr = new String(reply, 0, replyLen, "ASCII7");
- } catch (UnsupportedEncodingException ignored) {
- replyStr = new String(reply, 0, replyLen);
- }
-
- /* We check for Connection Established because our proxy returns HTTP/1.1 instead of 1.0 */
- if (replyStr.toLowerCase().indexOf("200 connection established") == -1) {
- throw new IOException("Unable to tunnel through. Proxy returns \"" + replyStr + "\"");
- }
-
- /* tunneling Handshake was successful! */
- }
-
-}
diff --git a/javapns/src/main/java/javapns/communication/KeystoreManager.java b/javapns/src/main/java/javapns/communication/KeystoreManager.java
deleted file mode 100644
index 7eeae891b..000000000
--- a/javapns/src/main/java/javapns/communication/KeystoreManager.java
+++ /dev/null
@@ -1,113 +0,0 @@
-package javapns.communication;
-
-import java.io.*;
-import java.security.*;
-import java.security.cert.*;
-
-import javapns.communication.exceptions.*;
-
-/**
- * Class responsible for dealing with keystores.
- *
- * @author Sylvain Pedneault
- */
-class KeystoreManager {
-
- /**
- * Loads a keystore.
- *
- * @param server The server the keystore is intended for
- * @return A loaded keystore
- * @throws KeyStoreException
- * @throws NoSuchAlgorithmException
- * @throws CertificateException
- * @throws IOException
- * @throws Exception
- */
- public static KeyStore loadKeystore(AppleServer server) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, Exception {
- return loadKeystore(server, server.getKeystoreStream());
- }
-
-
- /**
- * Loads a keystore.
- *
- * @param server The server the keystore is intended for
- * @param keystore The keystore to load (can be a File, an InputStream, a String for a file path, or a byte[] array)
- * @return A loaded keystore
- * @throws KeyStoreException
- * @throws NoSuchAlgorithmException
- * @throws CertificateException
- * @throws IOException
- * @throws Exception
- */
- public static KeyStore loadKeystore(AppleServer server, Object keystore) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, Exception {
- synchronized (server) {
- InputStream keystoreStream = streamKeystore(keystore);
- //System.out.println("Loading keystore from "+keystore+" synchronized on "+server);
- KeyStore keyStore;
- try {
- keyStore = KeyStore.getInstance(server.getKeystoreType());
- try {
- char[] password = KeystoreManager.getKeystorePasswordForSSL(server);
- keyStore.load(keystoreStream, password);
- } catch (Exception e) {
- e = getSimplerSSLException(e);
- throw e;
- }
- } finally {
- try {
- keystoreStream.close();
- } catch (Exception e) {
- }
- }
- return keyStore;
- }
- }
-
-
- static char[] getKeystorePasswordForSSL(AppleServer server) {
- String password = server.getKeystorePassword();
- if (password == null) password = "";
- // if (password != null && password.length() == 0) password = null;
- char[] passchars = password != null ? password.toCharArray() : null;
- return passchars;
- }
-
-
- static Exception getSimplerSSLException(Exception e) {
- if (e != null) {
- String msg = e.toString();
- if (msg.contains("javax.crypto.BadPaddingException")) {
- return new InvalidKeystorePasswordException();
- }
- if (msg.contains("DerInputStream.getLength(): lengthTag=127, too big")) {
- return new InvalidKeystoreFormatException();
- }
- if (msg.contains("java.lang.ArithmeticException: / by zero") || msg.contains("java.security.UnrecoverableKeyException: Get Key failed: / by zero")) {
- return new InvalidKeystorePasswordException("Blank passwords not supported (#38). You must create your keystore with a non-empty password.");
- }
- }
- return e;
- }
-
-
- /**
- * Given an object representing a keystore, returns an actual stream for that keystore.
- * Allows you to provide an actual keystore as an InputStream or a byte[] array,
- * or a reference to a keystore file as a File object or a String path.
- *
- *
- * @param keystore InputStream, File, byte[] or String (as a file path)
- * @return A stream to the keystore.
- * @throws FileNotFoundException
- */
- public static InputStream streamKeystore(Object keystore) throws FileNotFoundException {
- if (keystore instanceof InputStream) return (InputStream) keystore;
- else if (keystore instanceof File) return new BufferedInputStream(new FileInputStream((File) keystore));
- else if (keystore instanceof String) return new BufferedInputStream(new FileInputStream((String) keystore));
- else if (keystore instanceof byte[]) return new ByteArrayInputStream((byte[]) keystore);
- else throw new IllegalArgumentException("Unsupported keystore reference: " + keystore);
- }
-
-}
diff --git a/javapns/src/main/java/javapns/communication/ServerTrustingTrustManager.java b/javapns/src/main/java/javapns/communication/ServerTrustingTrustManager.java
deleted file mode 100644
index 5888c3f80..000000000
--- a/javapns/src/main/java/javapns/communication/ServerTrustingTrustManager.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package javapns.communication;
-
-import java.security.cert.*;
-
-import javax.net.ssl.*;
-
-/**
- * A trust manager that automatically trusts all servers.
- * Used to avoid having handshake errors with Apple's sandbox servers.
- *
- * @author Sylvain Pedneault
- */
-class ServerTrustingTrustManager implements X509TrustManager {
-
- public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
- throw new CertificateException("Client is not trusted.");
- }
-
-
- public void checkServerTrusted(X509Certificate[] chain, String authType) {
- // trust all servers
- }
-
-
- public X509Certificate[] getAcceptedIssuers() {
- return null;//new X509Certificate[0];
- }
-}
\ No newline at end of file
diff --git a/javapns/src/main/java/javapns/communication/exceptions/InvalidCertificateChainException.java b/javapns/src/main/java/javapns/communication/exceptions/InvalidCertificateChainException.java
deleted file mode 100644
index 89d9ad09b..000000000
--- a/javapns/src/main/java/javapns/communication/exceptions/InvalidCertificateChainException.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package javapns.communication.exceptions;
-
-/**
- * Thrown when we try to contact Apple with an invalid keystore or certificate chain.
- * @author Sylvain Pedneault
- *
- */
-@SuppressWarnings("serial")
-public class InvalidCertificateChainException extends Exception {
-
- /**
- * Constructor
- */
- public InvalidCertificateChainException() {
- super("Invalid certificate chain! Verify that the keystore you provided was produced according to specs...");
- }
-
-
- /**
- * Constructor with custom message
- * @param message
- */
- public InvalidCertificateChainException(String message) {
- super("Invalid certificate chain (" + message + ")! Verify that the keystore you provided was produced according to specs...");
- }
-
-}
diff --git a/javapns/src/main/java/javapns/communication/exceptions/InvalidKeystoreFormatException.java b/javapns/src/main/java/javapns/communication/exceptions/InvalidKeystoreFormatException.java
deleted file mode 100644
index de3d03320..000000000
--- a/javapns/src/main/java/javapns/communication/exceptions/InvalidKeystoreFormatException.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package javapns.communication.exceptions;
-
-/**
- * Thrown when we try to contact Apple with an invalid keystore format.
- * @author Sylvain Pedneault
- *
- */
-@SuppressWarnings("serial")
-public class InvalidKeystoreFormatException extends Exception {
-
- /**
- * Constructor
- */
- public InvalidKeystoreFormatException() {
- super("Invalid keystore format! Make sure it is PKCS12...");
- }
-
-
- /**
- * Constructor with custom message
- * @param message
- */
- public InvalidKeystoreFormatException(String message) {
- super(message);
- }
-
-}
diff --git a/javapns/src/main/java/javapns/communication/exceptions/InvalidKeystorePasswordException.java b/javapns/src/main/java/javapns/communication/exceptions/InvalidKeystorePasswordException.java
deleted file mode 100644
index 3eddc9207..000000000
--- a/javapns/src/main/java/javapns/communication/exceptions/InvalidKeystorePasswordException.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package javapns.communication.exceptions;
-
-/**
- * Thrown when we try to contact Apple with an invalid password for the keystore.
- * @author Sylvain Pedneault
- *
- */
-@SuppressWarnings("serial")
-public class InvalidKeystorePasswordException extends Exception {
-
- /**
- * Constructor
- */
- public InvalidKeystorePasswordException() {
- super("Invalid keystore password! Verify settings for connecting to Apple...");
- }
-
-
- /**
- * Constructor with custom message
- * @param message
- */
- public InvalidKeystorePasswordException(String message) {
- super(message);
- }
-
-}
diff --git a/javapns/src/main/java/javapns/devices/Device.java b/javapns/src/main/java/javapns/devices/Device.java
deleted file mode 100644
index e79582621..000000000
--- a/javapns/src/main/java/javapns/devices/Device.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package javapns.devices;
-
-import java.sql.*;
-
-/**
- * This is the common interface for all Devices.
- * It allows the DeviceFactory to support multiple
- * implementations of Device (in-memory, JPA-backed, etc.)
- *
- * @author Sylvain Pedneault
- */
-public interface Device {
-
- /**
- * An id representing a particular device.
- *
- * Note that this is a local reference to the device,
- * which is not related to the actual device UUID or
- * other device-specific identification. Most of the
- * time, this deviceId should be the same as the token.
- *
- * @return the device id
- */
- public String getDeviceId();
-
-
- /**
- * A device token.
- *
- * @return the device token
- */
- public String getToken();
-
-
- /**
- *
- * @return the last register
- */
- public Timestamp getLastRegister();
-
-
- /**
- * An id representing a particular device.
- *
- * Note that this is a local reference to the device,
- * which is not related to the actual device UUID or
- * other device-specific identification. Most of the
- * time, this deviceId should be the same as the token.
- *
- * @param id the device id
- */
- public void setDeviceId(String id);
-
-
- /**
- * Set the device token
- * @param token
- */
- public void setToken(String token);
-
-
- /**
- *
- * @param lastRegister the last register
- */
- public void setLastRegister(Timestamp lastRegister);
-
-}
\ No newline at end of file
diff --git a/javapns/src/main/java/javapns/devices/DeviceFactory.java b/javapns/src/main/java/javapns/devices/DeviceFactory.java
deleted file mode 100644
index 09de963eb..000000000
--- a/javapns/src/main/java/javapns/devices/DeviceFactory.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package javapns.devices;
-
-import javapns.devices.exceptions.*;
-
-/**
- * This is the common interface for all DeviceFactories.
- * It allows the PushNotificationManager to support multiple
- * implementations of DeviceFactory (in-memory, JPA-backed, etc.)
- *
- * @author Sylvain Pedneault
- */
-public interface DeviceFactory {
-
- /**
- * Add a device to the map
- * @param id The local device id
- * @param token The device token
- * @return The device created
- * @throws DuplicateDeviceException
- * @throws NullIdException
- * @throws NullDeviceTokenException
- */
- public Device addDevice(String id, String token) throws DuplicateDeviceException, NullIdException, NullDeviceTokenException, Exception;
-
-
- /**
- * Get a device according to his id
- * @param id The local device id
- * @return The device
- * @throws UnknownDeviceException
- * @throws NullIdException
- */
- public Device getDevice(String id) throws UnknownDeviceException, NullIdException;
-
-
- /**
- * Remove a device
- * @param id The local device id
- * @throws UnknownDeviceException
- * @throws NullIdException
- */
- public void removeDevice(String id) throws UnknownDeviceException, NullIdException;
-
-}
\ No newline at end of file
diff --git a/javapns/src/main/java/javapns/devices/exceptions/DuplicateDeviceException.java b/javapns/src/main/java/javapns/devices/exceptions/DuplicateDeviceException.java
deleted file mode 100644
index 6bfb26a39..000000000
--- a/javapns/src/main/java/javapns/devices/exceptions/DuplicateDeviceException.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package javapns.devices.exceptions;
-
-/**
- * Thrown when a Device already exist and we try to add it a second time
- * @author Maxime Peron
- */
-@SuppressWarnings("serial")
-public class DuplicateDeviceException extends Exception{
-
- /* Custom message for this exception */
- private String message;
-
- /**
- * Constructor
- */
- public DuplicateDeviceException(){
- this.message = "Client already exists";
- }
-
- /**
- * Constructor with custom message
- * @param message
- */
- public DuplicateDeviceException(String message){
- this.message = message;
- }
-
- /**
- * String representation
- */
- public String toString(){
- return this.message;
- }
-}
diff --git a/javapns/src/main/java/javapns/devices/exceptions/NullDeviceTokenException.java b/javapns/src/main/java/javapns/devices/exceptions/NullDeviceTokenException.java
deleted file mode 100644
index 2da7a5fc9..000000000
--- a/javapns/src/main/java/javapns/devices/exceptions/NullDeviceTokenException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package javapns.devices.exceptions;
-
-/**
- * Thrown when the given token is null
- * @author Maxime Peron
- *
- */
-@SuppressWarnings("serial")
-public class NullDeviceTokenException extends Exception{
-
- /* Custom message for this exception */
- private String message;
-
- /**
- * Constructor
- */
- public NullDeviceTokenException(){
- this.message = "Client already exists";
- }
-
- /**
- * Constructor with custom message
- * @param message
- */
- public NullDeviceTokenException(String message){
- this.message = message;
- }
-
- /**
- * String representation
- */
- public String toString(){
- return this.message;
- }
-}
diff --git a/javapns/src/main/java/javapns/devices/exceptions/NullIdException.java b/javapns/src/main/java/javapns/devices/exceptions/NullIdException.java
deleted file mode 100644
index 998ac8949..000000000
--- a/javapns/src/main/java/javapns/devices/exceptions/NullIdException.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package javapns.devices.exceptions;
-
-/**
- * Thrown when the given id is null
- * @author Maxime Peron
- */
-@SuppressWarnings("serial")
-public class NullIdException extends Exception{
-
- /* Custom message for this exception */
- private String message;
-
- /**
- * Constructor
- */
- public NullIdException(){
- this.message = "Client already exists";
- }
-
- /**
- * Constructor with custom message
- * @param message
- */
- public NullIdException(String message){
- this.message = message;
- }
-
- /**
- * String representation
- */
- public String toString(){
- return this.message;
- }
-}
diff --git a/javapns/src/main/java/javapns/devices/exceptions/UnknownDeviceException.java b/javapns/src/main/java/javapns/devices/exceptions/UnknownDeviceException.java
deleted file mode 100644
index 92b17b5eb..000000000
--- a/javapns/src/main/java/javapns/devices/exceptions/UnknownDeviceException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package javapns.devices.exceptions;
-
-/**
- * Thrown when we try to retrieve a device that doesn't exist
- * @author Maxime Peron
- *
- */
-@SuppressWarnings("serial")
-public class UnknownDeviceException extends Exception{
-
- /* Custom message for this exception */
- private String message;
-
- /**
- * Constructor
- */
- public UnknownDeviceException(){
- this.message = "Unknown client";
- }
-
- /**
- * Constructor with custom message
- * @param message
- */
- public UnknownDeviceException(String message){
- this.message = message;
- }
-
- /**
- * String representation
- */
- public String toString(){
- return this.message;
- }
-}
diff --git a/javapns/src/main/java/javapns/devices/implementations/basic/BasicDevice.java b/javapns/src/main/java/javapns/devices/implementations/basic/BasicDevice.java
deleted file mode 100644
index bf98ec3df..000000000
--- a/javapns/src/main/java/javapns/devices/implementations/basic/BasicDevice.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package javapns.devices.implementations.basic;
-
-import java.sql.Timestamp;
-
-import javapns.devices.*;
-
-/**
- * This class is used to represent a Device (iPhone)
- * @author Maxime Peron
- *
- */
-public class BasicDevice implements Device {
-
- /*
- * An id representing a particular device.
- *
- * Note that this is a local reference to the device,
- * which is not related to the actual device UUID or
- * other device-specific identification. Most of the
- * time, this deviceId should be the same as the token.
- */
- private String deviceId;
-
- /* The device token given by Apple Server, hexadecimal form, 64bits length */
- private String token;
-
- /* The last time a device registered */
- private Timestamp lastRegister;
-
-
- /**
- * Default constructor.
- * @param token The device token
- */
- public BasicDevice(String token) throws Exception {
- super();
- this.deviceId = token;
- this.token = token;
- this.lastRegister = new Timestamp(System.currentTimeMillis());
-
- validateTokenFormat(token);
-
- }
-
- public static void validateTokenFormat(String token) throws IllegalArgumentException {
- if (token==null) {
- throw new IllegalArgumentException("Device Token is null, and not the required 64 bytes...");
- }
- if (token.getBytes().length != 64) {
- //throw new IllegalArgumentException("Device Token has a length of [" + token.getBytes().length + "] and not the required 64 bytes!");
- }
- }
-
- /**
- * Constructor
- * @param id The device id
- * @param token The device token
- */
- public BasicDevice(String id, String token, Timestamp register) throws Exception {
- super();
- this.deviceId = id;
- this.token = token;
- this.lastRegister = register;
-
- validateTokenFormat(token);
-
- }
-
-
- /**
- * Getter
- * @return the device id
- */
- public String getDeviceId() {
- return deviceId;
- }
-
-
- /**
- * Getter
- * @return the device token
- */
- public String getToken() {
- return token;
- }
-
-
- /**
- * Getter
- * @return the last register
- */
- public Timestamp getLastRegister() {
- return lastRegister;
- }
-
-
- /**
- * Setter
- * @param id the device id
- */
- public void setDeviceId(String id) {
- this.deviceId = id;
- }
-
- /**
- * Setter the device token
- * @param token
- */
- public void setToken(String token) {
- this.token = token;
- }
-
-
- public void setLastRegister(Timestamp lastRegister) {
- this.lastRegister = lastRegister;
- }
-
-}
diff --git a/javapns/src/main/java/javapns/devices/implementations/basic/BasicDeviceFactory.java b/javapns/src/main/java/javapns/devices/implementations/basic/BasicDeviceFactory.java
deleted file mode 100644
index b8c29e7a1..000000000
--- a/javapns/src/main/java/javapns/devices/implementations/basic/BasicDeviceFactory.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package javapns.devices.implementations.basic;
-
-import java.sql.*;
-import java.util.*;
-
-import javapns.devices.*;
-import javapns.devices.exceptions.*;
-import javapns.notification.*;
-
-import org.apache.commons.lang.*;
-import com.genexus.diagnostics.core.*;
-
-/**
- * This class implements an in-memory DeviceFactory (backed by a Map).
- * Since this class does not persist Device objects, it should not be used in a production environment.
- *
- * NB : Future Improvement :
- * - Add a method to find a device knowing his token
- * - Add a method to update a device (timestamp or token)
- * - method to compare two devices, and replace when the device token has changed
- *
- * @author Maxime Peron
- *
- */
-public class BasicDeviceFactory implements DeviceFactory {
-
- protected static final ILogger logger = PushNotificationManager.logger;
-
- /* A map containing all the devices, identified with their id */
- private Map devices;
-
- /* synclock */
- private static final Object synclock = new Object();
-
-
- /**
- * Constructs a VolatileDeviceFactory
- */
- public BasicDeviceFactory() {
- this.devices = new HashMap();
- }
-
-
- /**
- * Add a device to the map
- * @param id The device id
- * @param token The device token
- * @throws DuplicateDeviceException
- * @throws NullIdException
- * @throws NullDeviceTokenException
- */
- public Device addDevice(String id, String token) throws DuplicateDeviceException, NullIdException, NullDeviceTokenException, Exception {
- if ((id == null) || (id.trim().equals(""))) {
- throw new NullIdException();
- } else if ((token == null) || (token.trim().equals(""))) {
- throw new NullDeviceTokenException();
- } else {
- if (!this.devices.containsKey(id)) {
- token = StringUtils.deleteWhitespace(token);
- BasicDevice device = new BasicDevice(id, token, new Timestamp(Calendar.getInstance().getTime().getTime()));
- this.devices.put(id, device);
- return device;
- } else {
- throw new DuplicateDeviceException();
- }
- }
- }
-
-
- /**
- * Get a device according to his id
- * @param id The device id
- * @return The device
- * @throws UnknownDeviceException
- * @throws NullIdException
- */
- public Device getDevice(String id) throws UnknownDeviceException, NullIdException {
- if ((id == null) || (id.trim().equals(""))) {
- throw new NullIdException();
- } else {
- if (this.devices.containsKey(id)) {
- return this.devices.get(id);
- } else {
- throw new UnknownDeviceException();
- }
- }
- }
-
-
- /**
- * Remove a device
- * @param id The device id
- * @throws UnknownDeviceException
- * @throws NullIdException
- */
- public void removeDevice(String id) throws UnknownDeviceException, NullIdException {
- if ((id == null) || (id.trim().equals(""))) {
- throw new NullIdException();
- }
- if (this.devices.containsKey(id)) {
- this.devices.remove(id);
- } else {
- throw new UnknownDeviceException();
- }
- }
-}
diff --git a/javapns/src/main/java/javapns/feedback/AppleFeedbackServer.java b/javapns/src/main/java/javapns/feedback/AppleFeedbackServer.java
deleted file mode 100644
index a99f55bdb..000000000
--- a/javapns/src/main/java/javapns/feedback/AppleFeedbackServer.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package javapns.feedback;
-
-import javapns.communication.*;
-
-/**
- * Interface representing a connection to an Apple Feedback Server
- *
- * @author Sylvain Pedneault
- */
-public interface AppleFeedbackServer extends AppleServer {
-
- public static final String PRODUCTION_HOST = "feedback.push.apple.com";
- public static final int PRODUCTION_PORT = 2196;
-
- public static final String DEVELOPMENT_HOST = "feedback.sandbox.push.apple.com";
- public static final int DEVELOPMENT_PORT = 2196;
-
-
- public String getFeedbackServerHost();
-
-
- public int getFeedbackServerPort();
-
-}
diff --git a/javapns/src/main/java/javapns/feedback/AppleFeedbackServerBasicImpl.java b/javapns/src/main/java/javapns/feedback/AppleFeedbackServerBasicImpl.java
deleted file mode 100644
index bc1ca833d..000000000
--- a/javapns/src/main/java/javapns/feedback/AppleFeedbackServerBasicImpl.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package javapns.feedback;
-
-import java.io.*;
-
-import javapns.communication.*;
-
-/**
- * Basic implementation of the AppleFeedbackServer interface,
- * intended to facilitate rapid deployment.
- *
- * @author Sylvain Pedneault
- */
-public class AppleFeedbackServerBasicImpl extends AppleServerBasicImpl implements AppleFeedbackServer {
-
- private String host;
- private int port;
-
-
- /**
- * Communication settings for interacting with Apple's default production or sandbox feedback server.
- * This constructor uses the recommended keystore type "PCKS12".
- *
- * @param keystore The keystore to use (can be a File, an InputStream, a String for a file path, or a byte[] array)
- * @param password The keystore's password
- * @param production true to use Apple's production servers, false to use the sandbox
- * @throws FileNotFoundException
- */
- public AppleFeedbackServerBasicImpl(Object keystore, String password, boolean production) throws FileNotFoundException {
- this(keystore, password, ConnectionToAppleServer.KEYSTORE_TYPE_PKCS12, production);
- }
-
-
- /**
- * Communication settings for interacting with Apple's default production or sandbox feedback server.
- *
- * @param keystore The keystore to use (can be a File, an InputStream, a String for a file path, or a byte[] array)
- * @param password The keystore's password
- * @param type The keystore's type
- * @param production true to use Apple's production servers, false to use the sandbox
- * @throws FileNotFoundException
- */
- public AppleFeedbackServerBasicImpl(Object keystore, String password, String type, boolean production) throws FileNotFoundException {
- this(keystore, password, type, production ? PRODUCTION_HOST : DEVELOPMENT_HOST, production ? PRODUCTION_PORT : DEVELOPMENT_PORT);
- }
-
-
- /**
- * Communication settings for interacting with a specific Apple Push Notification Feedback Server.
- *
- * @param keystore The keystore to use (can be a File, an InputStream, a String for a file path, or a byte[] array)
- * @param password The keystore's password
- * @param type The keystore's type
- * @param host A specific APNS host
- * @param port A specific APNS port
- * @throws FileNotFoundException
- */
- public AppleFeedbackServerBasicImpl(Object keystore, String password, String type, String host, int port) throws FileNotFoundException {
- super(keystore, password, type);
- this.host = host;
- this.port = port;
- }
-
-
- public String getFeedbackServerHost() {
- return host;
- }
-
-
- public int getFeedbackServerPort() {
- return port;
- }
-
-}
diff --git a/javapns/src/main/java/javapns/feedback/ConnectionToFeedbackServer.java b/javapns/src/main/java/javapns/feedback/ConnectionToFeedbackServer.java
deleted file mode 100644
index c423617ef..000000000
--- a/javapns/src/main/java/javapns/feedback/ConnectionToFeedbackServer.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package javapns.feedback;
-
-import java.io.*;
-import java.security.*;
-import java.security.cert.*;
-
-import javapns.communication.*;
-
-/**
- * Class representing a connection to a specific Feedback Server.
- *
- * @author Sylvain Pedneault
- */
-public class ConnectionToFeedbackServer extends ConnectionToAppleServer {
-
- public ConnectionToFeedbackServer(AppleFeedbackServer feedbackServer) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, Exception {
- super(feedbackServer);
- }
-
-
- @Override
- public String getServerHost() {
- return ((AppleFeedbackServer) getServer()).getFeedbackServerHost();
- }
-
-
- @Override
- public int getServerPort() {
- return ((AppleFeedbackServer) getServer()).getFeedbackServerPort();
- }
-
-}
diff --git a/javapns/src/main/java/javapns/feedback/FeedbackServiceManager.java b/javapns/src/main/java/javapns/feedback/FeedbackServiceManager.java
deleted file mode 100644
index 7c1bbfb08..000000000
--- a/javapns/src/main/java/javapns/feedback/FeedbackServiceManager.java
+++ /dev/null
@@ -1,181 +0,0 @@
-package javapns.feedback;
-
-import java.io.*;
-import java.security.*;
-import java.security.cert.*;
-import java.util.*;
-
-import javapns.devices.*;
-import javapns.devices.exceptions.*;
-import javapns.devices.implementations.basic.*;
-import javax.net.ssl.*;
-
-import com.genexus.diagnostics.core.*;
-
-
-/**
- * Class for interacting with a specific Feedback Service.
- *
- * @author kljajo, dgardon, Sylvain Pedneault
- *
- */
-public class FeedbackServiceManager {
-
- protected static final ILogger logger = LogManager.getLogger(FeedbackServiceManager.class);
-
- /* Length of the tuple sent by Apple */
- private static final int FEEDBACK_TUPLE_SIZE = 38;
-
- private boolean proxySet = false;
-
- private DeviceFactory deviceFactory;
-
-
- /**
- * Constructs a FeedbackServiceManager with a supplied DeviceFactory.
- */
- public FeedbackServiceManager(DeviceFactory deviceFactory) {
- this.setDeviceFactory(deviceFactory);
- }
-
-
- /**
- * Constructs a FeedbackServiceManager with a default basic DeviceFactory.
- */
- public FeedbackServiceManager() {
- this.setDeviceFactory(new BasicDeviceFactory());
- }
-
-
- /**
- * Retrieve all devices which have un-installed the application w/Path to keystore
- *
- * @param server Connection information for the Apple server
- * @return List of Devices
- * @throws IOException
- * @throws FileNotFoundException
- * @throws CertificateException
- * @throws NoSuchAlgorithmException
- * @throws KeyStoreException
- * @throws KeyManagementException
- * @throws UnrecoverableKeyException
- */
- /**
- */
- public LinkedList getDevices(AppleFeedbackServer server) throws UnrecoverableKeyException, KeyManagementException, KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException, NoSuchProviderException, Exception {
- // logger.debug( "Retrieving Devices from Host: [" + appleHost + "] Port: [" + applePort + "] with KeyStorePath [" + keyStorePath + "]/[" + keyStoreType + "]" );
- // Create the connection and open a socket
- ConnectionToFeedbackServer connectionHelper = new ConnectionToFeedbackServer(server);
- SSLSocket socket = connectionHelper.getSSLSocket();
-
- return getDevices(socket);
- }
-
-
- /**
- * Retrieves the list of devices from an established SSLSocket.
- *
- * @param socket
- * @return Devices
- * @throws Exception
- * @throws NullDeviceTokenException
- * @throws NullIdException
- * @throws DuplicateDeviceException
- */
- private LinkedList getDevices(SSLSocket socket) throws Exception {
-
- // Compute
- LinkedList listDev = null;
- try {
- InputStream socketStream = socket.getInputStream();
-
- // Read bytes
- byte[] b = new byte[1024];
- ByteArrayOutputStream message = new ByteArrayOutputStream();
- int nbBytes = 0;
- // socketStream.available can return 0
- // http://forums.sun.com/thread.jspa?threadID=5428561
- while ((nbBytes = socketStream.read(b, 0, 1024)) != -1) {
- message.write(b, 0, nbBytes);
- }
-
- listDev = new LinkedList();
- byte[] listOfDevices = message.toByteArray();
- int nbTuples = listOfDevices.length / FEEDBACK_TUPLE_SIZE;
- logger.debug("Found: [" + nbTuples + "]");
- for (int i = 0; i < nbTuples; i++) {
- int offset = i * FEEDBACK_TUPLE_SIZE;
-
- // Build date
- int index = 0;
- int firstByte = 0;
- int secondByte = 0;
- int thirdByte = 0;
- int fourthByte = 0;
- long anUnsignedInt = 0;
-
- firstByte = (0x000000FF & ((int) listOfDevices[offset]));
- secondByte = (0x000000FF & ((int) listOfDevices[offset + 1]));
- thirdByte = (0x000000FF & ((int) listOfDevices[offset + 2]));
- fourthByte = (0x000000FF & ((int) listOfDevices[offset + 3]));
- index = index + 4;
- anUnsignedInt = ((long) (firstByte << 24 | secondByte << 16 | thirdByte << 8 | fourthByte)) & 0xFFFFFFFFL;
-
- // Build device token length
- int deviceTokenLength = listOfDevices[offset + 4] << 8 | listOfDevices[offset + 5];
-
- // Build device token
- String deviceToken = "";
- int octet = 0;
- for (int j = 0; j < 32; j++) {
- octet = (0x000000FF & ((int) listOfDevices[offset + 6 + j]));
- deviceToken = deviceToken.concat(String.format("%02x", octet));
- }
-
- // Build device and add to list
- /* Create a basic device, as we do not want to go through the factory and create a device in the actual database... */
- Device device = new BasicDevice(deviceToken);
- listDev.add(device);
- logger.info("FeedbackManager retrieves one device : " + new Date(anUnsignedInt * 1000) + ";" + deviceTokenLength + ";" + deviceToken + ".");
- }
-
- // Close the socket and return the list
-
- } catch (Exception e) {
- logger.debug("Caught exception fetching devices from Feedback Service");
- throw e;
- }
-
- finally {
- socket.close();
- }
- return listDev;
- }
-
-
- /**
- * Set the proxy if needed
- * @param host the proxyHost
- * @param port the proxyPort
- */
- public void setProxy(String host, String port) {
- this.proxySet = true;
-
- System.setProperty("http.proxyHost", host);
- System.setProperty("http.proxyPort", port);
-
- System.setProperty("https.proxyHost", host);
- System.setProperty("https.proxyPort", port);
- }
-
-
- public void setDeviceFactory(DeviceFactory deviceFactory) {
- this.deviceFactory = deviceFactory;
- }
-
-
- public DeviceFactory getDeviceFactory() {
- return deviceFactory;
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/AppleNotificationServer.java b/javapns/src/main/java/javapns/notification/AppleNotificationServer.java
deleted file mode 100644
index 9fe85d45a..000000000
--- a/javapns/src/main/java/javapns/notification/AppleNotificationServer.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package javapns.notification;
-
-import javapns.communication.*;
-
-/**
- * Interface representing a connection to an Apple Notification Server
- *
- * @author Sylvain Pedneault
- */
-public interface AppleNotificationServer extends AppleServer {
-
- public static final String PRODUCTION_HOST = "gateway.push.apple.com";
- public static final int PRODUCTION_PORT = 2195;
-
- public static final String DEVELOPMENT_HOST = "gateway.sandbox.push.apple.com";
- public static final int DEVELOPMENT_PORT = 2195;
-
-
- public String getNotificationServerHost();
-
-
- public int getNotificationServerPort();
-
-}
diff --git a/javapns/src/main/java/javapns/notification/AppleNotificationServerBasicImpl.java b/javapns/src/main/java/javapns/notification/AppleNotificationServerBasicImpl.java
deleted file mode 100644
index faa52fe5c..000000000
--- a/javapns/src/main/java/javapns/notification/AppleNotificationServerBasicImpl.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package javapns.notification;
-
-import java.io.*;
-
-import javapns.communication.*;
-
-/**
- * Basic implementation of the AppleNotificationServer interface,
- * intended to facilitate rapid deployment.
- *
- * @author Sylvain Pedneault
- */
-public class AppleNotificationServerBasicImpl extends AppleServerBasicImpl implements AppleNotificationServer {
-
- private String host;
- private int port;
-
-
- /**
- * Communication settings for interacting with Apple's default production or sandbox notification server.
- * This constructor uses the recommended keystore type "PCKS12".
- *
- * @param keystore The keystore to use (can be a File, an InputStream, a String for a file path, or a byte[] array)
- * @param password The keystore's password
- * @param production true to use Apple's production servers, false to use the sandbox
- * @throws FileNotFoundException
- */
- public AppleNotificationServerBasicImpl(Object keystore, String password, boolean production) throws FileNotFoundException {
- this(keystore, password, ConnectionToAppleServer.KEYSTORE_TYPE_PKCS12, production);
- }
-
-
- /**
- * Communication settings for interacting with Apple's default production or sandbox notification server.
- *
- * @param keystore The keystore to use (can be a File, an InputStream, a String for a file path, or a byte[] array)
- * @param password The keystore's password
- * @param type The keystore's type
- * @param production true to use Apple's production servers, false to use the sandbox
- * @throws FileNotFoundException
- */
- public AppleNotificationServerBasicImpl(Object keystore, String password, String type, boolean production) throws FileNotFoundException {
- this(keystore, password, type, production ? PRODUCTION_HOST : DEVELOPMENT_HOST, production ? PRODUCTION_PORT : DEVELOPMENT_PORT);
- }
-
-
- /**
- * Communication settings for interacting with a specific Apple Push Notification Server.
- *
- * @param keystore The keystore to use (can be a File, an InputStream, a String for a file path, or a byte[] array)
- * @param password The keystore's password
- * @param type The keystore's type
- * @param host A specific APNS host
- * @param port A specific APNS port
- * @throws FileNotFoundException
- */
- public AppleNotificationServerBasicImpl(Object keystore, String password, String type, String host, int port) throws FileNotFoundException {
- super(keystore, password, type);
- this.host = host;
- this.port = port;
- }
-
-
- public String getNotificationServerHost() {
- return host;
- }
-
-
- public int getNotificationServerPort() {
- return port;
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/ConnectionToNotificationServer.java b/javapns/src/main/java/javapns/notification/ConnectionToNotificationServer.java
deleted file mode 100644
index 330d9c6e5..000000000
--- a/javapns/src/main/java/javapns/notification/ConnectionToNotificationServer.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package javapns.notification;
-
-import java.io.*;
-import java.security.*;
-import java.security.cert.*;
-
-import javapns.communication.*;
-
-/**
- * Connection details specific to the Notification Service.
- *
- * @author Sylvain Pedneault
- */
-public class ConnectionToNotificationServer extends ConnectionToAppleServer {
-
- public ConnectionToNotificationServer(AppleNotificationServer server) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, Exception {
- super(server);
- }
-
-
- @Override
- public String getServerHost() {
- return ((AppleNotificationServer) getServer()).getNotificationServerHost();
- }
-
-
- @Override
- public int getServerPort() {
- return ((AppleNotificationServer) getServer()).getNotificationServerPort();
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/NewsstandNotificationPayload.java b/javapns/src/main/java/javapns/notification/NewsstandNotificationPayload.java
deleted file mode 100644
index d5bd87f65..000000000
--- a/javapns/src/main/java/javapns/notification/NewsstandNotificationPayload.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package javapns.notification;
-
-import org.json.*;
-
-/**
- * A Newsstand-specific payload compatible with the Apple Push Notification Service.
- *
- * @author Sylvain Pedneault
- */
-public class NewsstandNotificationPayload extends Payload {
-
- /**
- * Create a pre-defined payload with a content-available property set to 1.
- *
- * @return a ready-to-send newsstand payload
- */
- public static NewsstandNotificationPayload contentAvailable() {
- NewsstandNotificationPayload payload = complex();
- try {
- payload.addContentAvailable();
- } catch (JSONException e) {
- }
- return payload;
- }
-
-
- /**
- * Create an empty payload which you can configure later (most users should not use this).
- * This method is usually used to create complex or custom payloads.
- * Note: the payload actually contains the default "aps"
- * dictionary required by Newsstand.
- *
- * @return a blank payload that can be customized
- */
- private static NewsstandNotificationPayload complex() {
- NewsstandNotificationPayload payload = new NewsstandNotificationPayload();
- return payload;
- }
-
- /* The application Dictionnary */
- private JSONObject apsDictionary;
-
-
- /**
- * Create a default payload with a blank "aps" dictionary.
- */
- NewsstandNotificationPayload() {
- super();
- this.apsDictionary = new JSONObject();
- try {
- JSONObject payload = getPayload();
- payload.put("aps", this.apsDictionary);
- } catch (JSONException e) {
- e.printStackTrace();
- }
- }
-
-
- void addContentAvailable() throws JSONException {
- addContentAvailable(1);
- }
-
-
- void addContentAvailable(int contentAvailable) throws JSONException {
- this.apsDictionary.put("content-available", contentAvailable);
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/Payload.java b/javapns/src/main/java/javapns/notification/Payload.java
deleted file mode 100644
index 0c5552c98..000000000
--- a/javapns/src/main/java/javapns/notification/Payload.java
+++ /dev/null
@@ -1,337 +0,0 @@
-package javapns.notification;
-
-import java.util.*;
-
-import javapns.devices.*;
-import javapns.notification.exceptions.*;
-
-import org.json.*;
-
-import com.genexus.diagnostics.core.*;
-
-/**
- * Abstract class representing a payload that can be transmitted to Apple.
- *
- * By default, this class has no payload content at all. Subclasses are
- * responsible for imposing specific content based on the specifications
- * they are intended to implement (such as the 'aps' dictionnary for APS
- * payloads).
- *
- * @author Sylvain Pedneault
- */
-public abstract class Payload {
-
- /* Character encoding specified by Apple documentation */
- private static final String DEFAULT_CHARACTER_ENCODING = "UTF-8";
-
- protected static final ILogger logger = LogManager.getLogger(DeviceFactory.class);
-
- /* The root Payload */
- private JSONObject payload;
-
- /* Character encoding to use for streaming the payload (should be UTF-8) */
- private String characterEncoding = DEFAULT_CHARACTER_ENCODING;
-
- /* Number of seconds after which this payload should expire */
- private int expiry = 1 * 24 * 60 * 60;
-
- private boolean payloadSizeEstimatedWhenAdding = false;
-
-
- /**
- * Constructor, instantiate the the root JSONObject
- */
- public Payload() {
- super();
- this.payload = new JSONObject();
- }
-
-
- public JSONObject getPayload() {
- return this.payload;
- }
-
-
- /**
- * Add a custom dictionnary with a string value
- * @param name
- * @param value
- * @throws JSONException
- */
- public void addCustomDictionary(String name, String value) throws JSONException {
- logger.debug("Adding custom Dictionary [" + name + "] = [" + value + "]");
- put(name, value, payload, false);
- }
-
-
- /**
- * Add a custom dictionnary with a int value
- * @param name
- * @param value
- * @throws JSONException
- */
- public void addCustomDictionary(String name, int value) throws JSONException {
- logger.debug("Adding custom Dictionary [" + name + "] = [" + value + "]");
- put(name, value, payload, false);
- }
-
-
- /**
- * Add a custom dictionnary with multiple values
- * @param name
- * @param values
- * @throws JSONException
- */
- public void addCustomDictionary(String name, List values) throws JSONException {
- logger.debug("Adding custom Dictionary [" + name + "] = (list)");
- put(name, values, payload, false);
- }
-
-
- /**
- * Get the string representation
- */
- public String toString() {
- return this.payload.toString();
- }
-
-
- /**
- * Get this payload as a byte array using the preconfigured character encoding.
- *
- * @return byte[] bytes ready to be streamed directly to Apple servers
- */
- public byte[] getPayloadAsBytes() throws Exception {
- byte[] payload = getPayloadAsBytesUnchecked();
- validateMaximumPayloadSize(payload.length);
- return payload;
- }
-
-
- /**
- * Get this payload as a byte array using the preconfigured character encoding.
- * This method does NOT check if the payload exceeds the maximum payload length.
- *
- * @return byte[] bytes ready to be streamed directly to Apple servers (but that might exceed the maximum size limit)
- */
- private byte[] getPayloadAsBytesUnchecked() throws Exception {
- byte[] bytes = null;
- try {
- bytes = toString().getBytes(characterEncoding);
- } catch (Exception ex) {
- bytes = toString().getBytes();
- }
- return bytes;
- }
-
-
- /**
- * Get the number of bytes that the payload will occupy when streamed.
- *
- * @return a number of bytes
- * @throws Exception
- */
- public int getPayloadSize() throws Exception {
- return getPayloadAsBytesUnchecked().length;
- }
-
-
- /**
- * Check if the payload exceeds the maximum size allowed.
- * The maximum size allowed is returned by the getMaximumPayloadSize() method.
- *
- * @return true if the payload exceeds the maximum size allowed, false otherwise
- */
- private boolean isPayloadTooLong() {
- try {
- byte[] bytes = getPayloadAsBytesUnchecked();
- if (bytes.length > getMaximumPayloadSize()) return true;
- } catch (Exception e) {
- }
- return false;
- }
-
-
- /**
- * Estimate the size that this payload will take after adding a given property.
- * For performance reasons, this estimate is not as reliable as actually adding
- * the property and checking the payload size afterwards.
- *
- * Currently works well with strings and numbers.
- *
- * @param propertyName the name of the property to use for calculating the estimation
- * @param propertyValue the value of the property to use for calculating the estimation
- * @return an estimated payload size if the property were to be added to the payload
- */
- public int estimatePayloadSizeAfterAdding(String propertyName, Object propertyValue) {
- try {
- int maximumPayloadSize = getMaximumPayloadSize();
- int currentPayloadSize = getPayloadAsBytesUnchecked().length;
- int estimatedSize = currentPayloadSize;
- if (propertyName != null && propertyValue != null) {
- estimatedSize += 5; // "":""
- estimatedSize += propertyName.getBytes(getCharacterEncoding()).length;
- int estimatedValueSize = 0;
-
- if (propertyValue instanceof String || propertyValue instanceof Number) estimatedValueSize = propertyValue.toString().getBytes(getCharacterEncoding()).length;
-
- estimatedSize += estimatedValueSize;
- }
- return estimatedSize;
- } catch (Exception e) {
- try {
- return getPayloadSize();
- } catch (Exception e1) {
- return 0;
- }
- }
- }
-
-
- /**
- * Validate if the estimated payload size after adding a given property will be allowed.
- * For performance reasons, this estimate is not as reliable as actually adding
- * the property and checking the payload size afterwards.
- *
- * @param propertyName the name of the property to use for calculating the estimation
- * @param propertyValue the value of the property to use for calculating the estimation
- * @return true if the payload size is not expected to exceed the maximum allowed, false if it might be too big
- */
- public boolean isEstimatedPayloadSizeAllowedAfterAdding(String propertyName, Object propertyValue) {
- int maximumPayloadSize = getMaximumPayloadSize();
- int estimatedPayloadSize = estimatePayloadSizeAfterAdding(propertyName, propertyValue);
- boolean estimatedToBeAllowed = estimatedPayloadSize <= maximumPayloadSize;
- return estimatedToBeAllowed;
- }
-
-
- /**
- * Validate that the payload does not exceed the maximum size allowed.
- * If the limit is exceeded, a PayloadMaxSizeExceededException is thrown.
- *
- * @param currentPayloadSize the total size of the payload in bytes
- * @throws PayloadMaxSizeExceededException if the payload exceeds the maximum size allowed
- */
- private void validateMaximumPayloadSize(int currentPayloadSize) throws PayloadMaxSizeExceededException {
- int maximumPayloadSize = getMaximumPayloadSize();
- if (currentPayloadSize > maximumPayloadSize) {
- throw new PayloadMaxSizeExceededException(maximumPayloadSize, currentPayloadSize);
- }
- }
-
-
- /**
- * Puts a property in a JSONObject, while possibly checking for estimated payload size violation.
- *
- * @param propertyName the name of the property to use for calculating the estimation
- * @param propertyValue the value of the property to use for calculating the estimation
- * @param object the JSONObject to put the property in
- * @param opt true to use putOpt, false to use put
- * @throws JSONException
- */
- protected void put(String propertyName, Object propertyValue, JSONObject object, boolean opt) throws JSONException {
- try {
- if (isPayloadSizeEstimatedWhenAdding()) {
- int maximumPayloadSize = getMaximumPayloadSize();
- int estimatedPayloadSize = estimatePayloadSizeAfterAdding(propertyName, propertyValue);
- boolean estimatedToExceed = estimatedPayloadSize > maximumPayloadSize;
- if (estimatedToExceed) throw new PayloadMaxSizeProbablyExceededException(maximumPayloadSize, estimatedPayloadSize);
- }
- } catch (PayloadMaxSizeProbablyExceededException e) {
- throw e;
- } catch (Exception e) {
-
- }
- if (opt) object.putOpt(propertyName, propertyValue);
- else object.put(propertyName, propertyValue);
- }
-
-
- /**
- * Indicates if payload size is estimated and controlled when adding properties (default is false).
- *
- * @return true to throw an exception if the estimated size is too big when adding a property, false otherwise
- */
- public boolean isPayloadSizeEstimatedWhenAdding() {
- return payloadSizeEstimatedWhenAdding;
- }
-
-
- /**
- * Indicate if payload size should be estimated and controlled when adding properties (default is false).
- * @param checked true to throw an exception if the estimated size is too big when adding a property, false otherwise
- */
- public void setPayloadSizeEstimatedWhenAdding(boolean checked) {
- this.payloadSizeEstimatedWhenAdding = checked;
- }
-
-
- /**
- * Return the maximum payload size in bytes.
- * By default, this method returns Integer.MAX_VALUE.
- * Subclasses should override this method to provide their own limit.
- *
- * @return the maximum payload size in bytes
- */
- public int getMaximumPayloadSize() {
- return Integer.MAX_VALUE;
- }
-
-
- /**
- * Changes the character encoding for streaming the payload.
- * Character encoding is preset to UTF-8, as Apple documentation specifies.
- * Therefore, unless you are working on a special project, you should leave it as is.
- *
- * @param characterEncoding a valid character encoding that String.getBytes(encoding) will accept
- */
- public void setCharacterEncoding(String characterEncoding) {
- this.characterEncoding = characterEncoding;
- }
-
-
- /**
- * Returns the character encoding that will be used by getPayloadAsBytes().
- * Default is UTF-8, as per Apple documentation.
- *
- * @return a character encoding
- */
- public String getCharacterEncoding() {
- return characterEncoding;
- }
-
-
- /**
- * Set the number of seconds after which this payload should expire.
- * Default is one (1) day.
- *
- * @param seconds
- */
- public void setExpiry(int seconds) {
- this.expiry = seconds;
- }
-
-
- /**
- * Return the number of seconds after which this payload should expire.
- *
- * @return a number of seconds
- */
- public int getExpiry() {
- return expiry;
- }
-
-
- /**
- * Enables a special simulation mode which causes the library to behave
- * as usual *except* that at the precise point where the payload would
- * actually be streamed out to Apple, it is not.
- *
- * @return the same payload
- */
- public Payload asSimulationOnly() {
- setExpiry(919191);
- return this;
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/PayloadPerDevice.java b/javapns/src/main/java/javapns/notification/PayloadPerDevice.java
deleted file mode 100644
index 7a1b7a805..000000000
--- a/javapns/src/main/java/javapns/notification/PayloadPerDevice.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package javapns.notification;
-
-import javapns.devices.*;
-import javapns.devices.implementations.basic.*;
-
-/**
- * A one-to-one link between a payload and device.
- * Provides support for a typical payload-per-device scenario.
- *
- * @author Sylvain Pedneault
- */
-public class PayloadPerDevice {
-
- private Payload payload;
- private Device device;
-
-
- public PayloadPerDevice(Payload payload, String token) throws Exception {
- super();
- this.payload = payload;
- this.device = new BasicDevice(token);
- }
-
-
- public PayloadPerDevice(Payload payload, Device device) {
- super();
- this.payload = payload;
- this.device = device;
- }
-
-
- public Payload getPayload() {
- return payload;
- }
-
-
- public Device getDevice() {
- return device;
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/PushNotificationManager.java b/javapns/src/main/java/javapns/notification/PushNotificationManager.java
deleted file mode 100644
index 764d350e8..000000000
--- a/javapns/src/main/java/javapns/notification/PushNotificationManager.java
+++ /dev/null
@@ -1,627 +0,0 @@
-package javapns.notification;
-
-import java.io.*;
-import java.net.*;
-import java.nio.*;
-import java.security.*;
-import java.security.cert.*;
-import java.util.*;
-
-import javapns.communication.*;
-import javapns.communication.exceptions.*;
-import javapns.devices.*;
-import javapns.devices.exceptions.*;
-import javapns.devices.implementations.basic.*;
-
-import javax.net.ssl.*;
-
-import com.genexus.diagnostics.core.*;
-/**
- * The main class used to send notification and handle a connection to Apple SSLServerSocket.
- * This class is not multi-threaded. One instance per thread must be created.
- *
- * @author Maxime Pilon
- * @author Sylvain Pedneault
- * @author Others...
- */
-public class PushNotificationManager {
-
- /*
- * Number of milliseconds to use as socket timeout.
- * Set to -1 to leave the timeout to its default setting.
- */
- private int sslSocketTimeout = 30 * 1000;
-
- public static final ILogger logger = LogManager.getLogger(PushNotificationManager.class);
-
- /* Default retries for a connection */
- private static final int DEFAULT_RETRIES = 3;
-
- /* Special identifier that tells the manager to generate a sequential identifier for each payload pushed */
- private static final int SEQUENTIAL_IDENTIFIER = -1;
-
- /* Connection helper */
- private ConnectionToAppleServer connectionToAppleServer;
-
- /* The always connected SSLSocket */
- private SSLSocket socket;
-
- /* Default retry attempts */
- private int retryAttempts = DEFAULT_RETRIES;
-
- private int nextMessageIdentifier = 1;
-
- /*
- * To circumvent an issue with invalid server certificates,
- * set to true to use a trust manager that will always accept
- * server certificates, regardless of their validity.
- */
- private boolean trustAllServerCertificates = true;
-
- private boolean proxySet = false;
-
- /* The DeviceFactory to use with this PushNotificationManager */
- private DeviceFactory deviceFactory;
-
- private LinkedHashMap pushedNotifications = new LinkedHashMap();
-
-
- /**
- * Constructs a PushNotificationManager with a default DeviceFactory;
- * Must allow the device factory to be replaced later, to support IoC.
- */
- public PushNotificationManager() {
- deviceFactory = new BasicDeviceFactory();
- }
-
-
- /**
- * Constructs a PushNotificationManager using a supplied DeviceFactory
- * @param deviceManager
- */
- public PushNotificationManager(DeviceFactory deviceManager) {
- this.deviceFactory = deviceManager;
- }
-
-
- /**
- * Initialize the connection and create a SSLSocket
- * @param server The Apple Server to connect to.
- * @throws Exception
- */
- public void initializeConnection(AppleNotificationServer server) throws Exception {
- this.connectionToAppleServer = new ConnectionToNotificationServer(server);
- this.socket = connectionToAppleServer.getSSLSocket();
- logger.debug("Initialized Connection to Host: [" + server.getNotificationServerHost() + "] Port: [" + server.getNotificationServerPort() + "]: " + socket);
- }
-
-
- public void initializePreviousConnection() throws Exception {
- initializeConnection((AppleNotificationServer) this.connectionToAppleServer.getServer());
- }
-
-
- public void restartConnection(AppleNotificationServer server) throws Exception {
- stopConnection();
- initializeConnection(server);
- }
-
-
- private void restartPreviousConnection() throws Exception {
- try {
- logger.debug("Closing connection to restart previous one");
- this.socket.close();
- } catch (Exception e) {
- /* Do not complain if connection is already closed... */
- }
- initializePreviousConnection();
- }
-
-
- /**
- * Read and process any pending error-responses, and then close the connection.
- *
- * @throws IOException
- */
- public void stopConnection() throws Exception {
- processedFailedNotifications();
- try {
- logger.debug("Closing connection");
- this.socket.close();
- } catch (Exception e) {
- /* Do not complain if connection is already closed... */
- }
- }
-
-
- private int processedFailedNotifications() throws Exception {
- logger.debug("Reading responses");
- int responsesReceived = ResponsePacketReader.processResponses(this);
- while (responsesReceived > 0) {
- PushedNotification skippedNotification = null;
- List notificationsToResend = new ArrayList();
- boolean foundFirstFail = false;
- for (PushedNotification notification : pushedNotifications.values()) {
- if (foundFirstFail || !notification.isSuccessful()) {
- if (foundFirstFail) notificationsToResend.add(notification);
- else {
- foundFirstFail = true;
- skippedNotification = notification;
- }
- }
- }
- pushedNotifications.clear();
- int toResend = notificationsToResend.size();
- logger.debug("Found " + toResend + " notifications that must be re-sent");
- if (toResend > 0) {
- logger.debug("Restarting connection to resend notifications");
- restartPreviousConnection();
- for (PushedNotification pushedNotification : notificationsToResend) {
- sendNotification(pushedNotification, false);
- }
- }
- int remaining = responsesReceived = ResponsePacketReader.processResponses(this);
- if (remaining == 0) {
- logger.debug("No notifications remaining to be resent");
- return 0;
- }
- }
- return responsesReceived;
- }
-
-
- /**
- * Send a notification to a single device and close the connection.
- *
- * @param device the device to be notified
- * @param payload the payload to send
- * @return a pushed notification with details on transmission result and error (if any)
- * @throws UnrecoverableKeyException
- * @throws KeyManagementException
- * @throws KeyStoreException
- * @throws NoSuchAlgorithmException
- * @throws CertificateException
- * @throws FileNotFoundException
- * @throws IOException
- * @throws Exception
- */
- public PushedNotification sendNotification(Device device, Payload payload) throws UnrecoverableKeyException, KeyManagementException, KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException, Exception {
- return sendNotification(device, payload, true);
- }
-
-
- /**
- * Send a notification to a multiple devices in a single connection and close the connection.
- *
- * @param payload the payload to send
- * @param devices the device to be notified
- * @return a list of pushed notifications, each with details on transmission results and error (if any)
- * @throws UnrecoverableKeyException
- * @throws KeyManagementException
- * @throws KeyStoreException
- * @throws NoSuchAlgorithmException
- * @throws CertificateException
- * @throws FileNotFoundException
- * @throws IOException
- * @throws Exception
- */
- public List sendNotifications(Payload payload, List devices) throws UnrecoverableKeyException, KeyManagementException, KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException, Exception {
- List notifications = new Vector();
- for (Device device : devices)
- notifications.add(sendNotification(device, payload, false, SEQUENTIAL_IDENTIFIER));
- stopConnection();
- return notifications;
- }
-
-
- /**
- * Send a notification to a multiple devices in a single connection and close the connection.
- *
- * @param payload the payload to send
- * @param devices the device to be notified
- * @return a list of pushed notifications, each with details on transmission results and error (if any)
- * @throws UnrecoverableKeyException
- * @throws KeyManagementException
- * @throws KeyStoreException
- * @throws NoSuchAlgorithmException
- * @throws CertificateException
- * @throws FileNotFoundException
- * @throws IOException
- * @throws Exception
- */
- public List sendNotifications(Payload payload, Device... devices) throws UnrecoverableKeyException, KeyManagementException, KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException, Exception {
- List notifications = new Vector();
- for (Device device : devices)
- notifications.add(sendNotification(device, payload, false, SEQUENTIAL_IDENTIFIER));
- stopConnection();
- return notifications;
- }
-
-
- /**
- * Send a notification (Payload) to the given device
- *
- * @param device the device to be notified
- * @param payload the payload to send
- * @param closeAfter indicates if the connection should be closed after the payload has been sent
- * @return a pushed notification with details on transmission result and error (if any)
- * @throws UnrecoverableKeyException
- * @throws KeyManagementException
- * @throws KeyStoreException
- * @throws NoSuchAlgorithmException
- * @throws CertificateException
- * @throws FileNotFoundException
- * @throws IOException
- */
- public PushedNotification sendNotification(Device device, Payload payload, boolean closeAfter) throws UnrecoverableKeyException, KeyManagementException, KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException, Exception {
- return sendNotification(device, payload, closeAfter, SEQUENTIAL_IDENTIFIER);
- }
-
-
- /**
- * Send a notification (Payload) to the given device
- *
- * @param device the device to be notified
- * @param payload the payload to send
- * @param identifier a unique identifier which will match any error reported later (if any)
- * @return a pushed notification with details on transmission result and error (if any)
- * @throws UnrecoverableKeyException
- * @throws KeyManagementException
- * @throws KeyStoreException
- * @throws NoSuchAlgorithmException
- * @throws CertificateException
- * @throws FileNotFoundException
- * @throws IOException
- */
- public PushedNotification sendNotification(Device device, Payload payload, int identifier) throws UnrecoverableKeyException, KeyManagementException, KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException, Exception {
- return sendNotification(device, payload, false, identifier);
- }
-
-
- /**
- * Send a notification (Payload) to the given device
- *
- * @param device the device to be notified
- * @param payload the payload to send
- * @param closeAfter indicates if the connection should be closed after the payload has been sent
- * @param identifier a unique identifier which will match any error reported later (if any)
- * @return a pushed notification with details on transmission result and error (if any)
- * @throws UnrecoverableKeyException
- * @throws KeyManagementException
- * @throws KeyStoreException
- * @throws NoSuchAlgorithmException
- * @throws CertificateException
- * @throws FileNotFoundException
- * @throws IOException
- * @return TransmissionEnvelope an object that encapsulates all message transmission results
- */
- public PushedNotification sendNotification(Device device, Payload payload, boolean closeAfter, int identifier) throws UnrecoverableKeyException, KeyManagementException, KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException, Exception {
- PushedNotification pushedNotification = new PushedNotification(device, payload, identifier);
- sendNotification(pushedNotification, closeAfter);
- return pushedNotification;
- }
-
-
- /**
- * Actual action of sending a notification
- *
- * @param notification the ready-to-push notification
- * @param closeAfter indicates if the connection should be closed after the payload has been sent
- * @return a pushed notification with details on transmission result and error (if any)
- * @throws UnrecoverableKeyException
- * @throws KeyManagementException
- * @throws KeyStoreException
- * @throws NoSuchAlgorithmException
- * @throws CertificateException
- * @throws FileNotFoundException
- * @throws IOException
- * @return TransmissionEnvelope an object that encapsulates all message transmission results
- */
- private void sendNotification(PushedNotification notification, boolean closeAfter) throws UnrecoverableKeyException, KeyManagementException, KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException, Exception {
- try {
- Device device = notification.getDevice();
- Payload payload = notification.getPayload();
- if (notification.getIdentifier() <= 0) notification.setIdentifier(newMessageIdentifier());
- if (!pushedNotifications.containsKey(notification.getIdentifier())) pushedNotifications.put(notification.getIdentifier(), notification);
- int identifier = notification.getIdentifier();
-
- String token = device.getToken();
- // even though the BasicDevice constructor validates the token, we revalidate it in case we were passed another implementation of Device
- BasicDevice.validateTokenFormat(token);
- // PushedNotification pushedNotification = new PushedNotification(device, payload);
- byte[] bytes = getMessage(token, payload, identifier, notification);
- // pushedNotifications.put(pushedNotification.getIdentifier(), pushedNotification);
-
- /* Special simulation mode to skip actual streaming of message */
- boolean simulationMode = payload.getExpiry() == 919191;
-
- boolean success = false;
-
- BufferedReader in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
- int socketTimeout = getSslSocketTimeout();
- if (socketTimeout > 0) this.socket.setSoTimeout(socketTimeout);
- notification.setTransmissionAttempts(0);
- // Keep trying until we have a success
- while (!success) {
- try {
- logger.debug("Attempting to send notification: " + payload.toString() + "");
- logger.debug(" to device: " + token + "");
- notification.addTransmissionAttempt();
- try {
- if (!simulationMode) {
- this.socket.getOutputStream().write(bytes);
- } else {
- logger.debug("* Simulation only: would have streamed " + bytes.length + "-bytes message now..");
- }
- } catch (Exception e) {
- if (e != null) {
- if (e.toString().contains("certificate_unknown")) {
- throw new InvalidCertificateChainException(e.getMessage());
- }
- }
- throw e;
- }
- logger.debug("Flushing");
- this.socket.getOutputStream().flush();
- success = true;
- logger.debug("Notification sent on " + notification.getLatestTransmissionAttempt());
- notification.setTransmissionCompleted(true);
-
- } catch (IOException e) {
- // throw exception if we surpassed the valid number of retry attempts
- if (notification.getTransmissionAttempts() >= retryAttempts) {
- logger.error("Attempt to send Notification failed and beyond the maximum number of attempts permitted");
- notification.setTransmissionCompleted(false);
- notification.setException(e);
- logger.error("Delivery error", e);
- throw e;
-
- } else {
- logger.info("Attempt failed (" + e.getMessage() + ")... trying again");
- //Try again
- try {
- this.socket.close();
- } catch (Exception e2) {
- // do nothing
- }
- this.socket = connectionToAppleServer.getSSLSocket();
- if (socketTimeout > 0) this.socket.setSoTimeout(socketTimeout);
- }
- }
- }
- } catch (Exception ex) {
- notification.setException(ex);
- logger.error("Delivery error", ex);
- try {
- if (closeAfter) {
- logger.error("Closing connection after error");
- stopConnection();
- }
- } catch (Exception e) {
- }
- }
- }
-
-
- /**
- * Add a device
- * @param id The device id
- * @param token The device token
- * @throws DuplicateDeviceException
- * @throws NullDeviceTokenException
- * @throws NullIdException
- */
- public void addDevice(String id, String token) throws DuplicateDeviceException, NullIdException, NullDeviceTokenException, Exception {
- logger.debug("Adding Token [" + token + "] to Device [" + id + "]");
- deviceFactory.addDevice(id, token);
- }
-
-
- /**
- * Get a device according to his id
- * @param id The device id
- * @return The device
- * @throws UnknownDeviceException
- * @throws NullIdException
- */
- public Device getDevice(String id) throws UnknownDeviceException, NullIdException {
- logger.debug("Getting Token from Device [" + id + "]");
- return deviceFactory.getDevice(id);
- }
-
-
- /**
- * Remove a device
- * @param id The device id
- * @throws UnknownDeviceException
- * @throws NullIdException
- */
- public void removeDevice(String id) throws UnknownDeviceException, NullIdException {
- logger.debug("Removing Token from Device [" + id + "]");
- deviceFactory.removeDevice(id);
- }
-
-
- /**
- * Set the proxy if needed
- * @param host the proxyHost
- * @param port the proxyPort
- */
- public void setProxy(String host, String port) {
- proxySet = true;
-
- System.setProperty("http.proxyHost", host);
- System.setProperty("http.proxyPort", port);
-
- System.setProperty("https.proxyHost", host);
- System.setProperty("https.proxyPort", port);
- }
-
-
- /**
- * Compose the Raw Interface that will be sent through the SSLSocket
- * A notification message is
- * COMMAND | TOKENLENGTH | DEVICETOKEN | PAYLOADLENGTH | PAYLOAD
- * NEW!
- * COMMAND | !Identifier! | !Expiry! | TOKENLENGTH| DEVICETOKEN | PAYLOADLENGTH | PAYLOAD
- * See page 30 of Apple Push Notification Service Programming Guide
- * @param deviceToken the deviceToken
- * @param payload the payload
- * @param message
- * @return the byteArray to write to the SSLSocket OutputStream
- * @throws IOException
- */
- private byte[] getMessage(String deviceToken, Payload payload, int identifier, PushedNotification message) throws IOException, Exception {
- logger.debug("Building Raw message from deviceToken and payload");
-
- /* To test with a corrupted or invalid token, uncomment following line*/
- //deviceToken = deviceToken.substring(0,10);
-
- // First convert the deviceToken (in hexa form) to a binary format
- /*byte[] deviceTokenAsBytes = new byte[deviceToken.length() / 2];
- deviceToken = deviceToken.toUpperCase();
- int j = 0;
- for (int i = 0; i < deviceToken.length(); i += 2) {
- String t = deviceToken.substring(i, i + 2);
- int tmp = Integer.parseInt(t, 16);
- deviceTokenAsBytes[j++] = (byte) tmp;
- }*/
-
- byte[] deviceTokenAsBytes = com.genexus.util.Codecs.base64Decode(deviceToken.getBytes());
-
- // Create the ByteArrayOutputStream which will contain the raw interface
- byte[] payloadAsBytes = payload.getPayloadAsBytes();
- int size = (Byte.SIZE / Byte.SIZE) + (Character.SIZE / Byte.SIZE) + deviceTokenAsBytes.length + (Character.SIZE / Byte.SIZE) + payloadAsBytes.length;
- ByteArrayOutputStream bao = new ByteArrayOutputStream(size);
-
- // Write command to ByteArrayOutputStream
- // 0 = simple
- // 1 = enhanced
- byte b = 1;
- bao.write(b);
-
- // 4 bytes identifier (which will match any error packet received later on)
- bao.write(intTo4ByteArray(identifier));
- message.setIdentifier(identifier);
-
- // 4 bytes
- int requestedExpiry = payload.getExpiry();
- if (requestedExpiry <= 0) {
- bao.write(intTo4ByteArray(requestedExpiry));
- message.setExpiry(0);
- } else {
- long ctime = System.currentTimeMillis();
- long ttl = requestedExpiry * 1000; // time-to-live in milliseconds
- Long expiryDateInSeconds = ((ctime + ttl) / 1000L);
- bao.write(intTo4ByteArray(expiryDateInSeconds.intValue()));
- message.setExpiry(ctime + ttl);
- }
-
- // Write the TokenLength as a 16bits unsigned int, in big endian
- int tl = deviceTokenAsBytes.length;
- bao.write((byte) ((tl & 0xFF00) >> 8));
- bao.write((byte) (tl & 0xFF));
-
- // Write the Token in bytes
- bao.write(deviceTokenAsBytes);
-
- // Write the PayloadLength as a 16bits unsigned int, in big endian
- int pl = payloadAsBytes.length;
- int s1 = (pl & 0xFF00) >> 8;
- int s2 = pl & 0xFF;
- bao.write(s1);
- bao.write(s2);
-
- // Finally write the Payload
- bao.write(payloadAsBytes);
-
- logger.debug("Built raw message ID " + identifier);
-
- // Return the ByteArrayOutputStream as a Byte Array
- return bao.toByteArray();
- }
-
-
- /**
- * Get the number of retry attempts
- * @return int
- */
- public int getRetryAttempts() {
- return this.retryAttempts;
- }
-
-
- private static final byte[] intTo4ByteArray(int value) {
- return ByteBuffer.allocate(4).putInt(value).array();
- }
-
-
- /**
- * Set the number of retry attempts
- * @param retryAttempts
- */
- public void setRetryAttempts(int retryAttempts) {
- this.retryAttempts = retryAttempts;
- }
-
-
- /**
- * Sets the DeviceFactory used by this PushNotificationManager.
- * Usually useful for dependency injection.
- * @param deviceFactory an object implementing DeviceFactory
- */
- public void setDeviceFactory(DeviceFactory deviceFactory) {
- this.deviceFactory = deviceFactory;
- }
-
-
- /**
- * Returns the DeviceFactory used by this PushNotificationManager.
- * @return the DeviceFactory in use
- */
- public DeviceFactory getDeviceFactory() {
- return deviceFactory;
- }
-
-
- public void setSslSocketTimeout(int sslSocketTimeout) {
- this.sslSocketTimeout = sslSocketTimeout;
- }
-
-
- public int getSslSocketTimeout() {
- return sslSocketTimeout;
- }
-
-
- public void setTrustAllServerCertificates(boolean trustAllServerCertificates) {
- this.trustAllServerCertificates = trustAllServerCertificates;
- }
-
-
- public boolean isTrustAllServerCertificates() {
- return trustAllServerCertificates;
- }
-
-
- /**
- * Return a new sequential message identifier.
- *
- * @return a message identifier unique to this PushNotificationManager
- */
- private int newMessageIdentifier() {
- int id = nextMessageIdentifier;
- nextMessageIdentifier++;
- return id;
- }
-
-
- public Socket getActiveSocket() {
- return socket;
- }
-
-
- public Map getPushedNotifications() {
- return pushedNotifications;
- }
-}
diff --git a/javapns/src/main/java/javapns/notification/PushNotificationPayload.java b/javapns/src/main/java/javapns/notification/PushNotificationPayload.java
deleted file mode 100644
index 5fa1926b8..000000000
--- a/javapns/src/main/java/javapns/notification/PushNotificationPayload.java
+++ /dev/null
@@ -1,300 +0,0 @@
-package javapns.notification;
-
-import java.util.*;
-
-import javapns.notification.exceptions.*;
-
-import org.json.*;
-
-/**
- * A payload compatible with the Apple Push Notification Service.
- *
- * @author Maxime Peron
- * @author Sylvain Pedneault
- */
-public class PushNotificationPayload extends Payload {
-
- /* Maximum total length (serialized) of a payload */
- private static final int MAXIMUM_PAYLOAD_LENGTH = 256;
-
-
- /**
- * Create a pre-defined payload with a simple alert message.
- *
- * @param message the alert's message
- * @return a ready-to-send payload
- */
- public static Payload alert(String message) {
- PushNotificationPayload payload = complex();
- try {
- payload.addAlert(message);
- } catch (JSONException e) {
- }
- return payload;
- }
-
-
- /**
- * Create a pre-defined payload with a badge.
- *
- * @param badge the badge
- * @return a ready-to-send payload
- */
- public static Payload badge(int badge) {
- PushNotificationPayload payload = complex();
- try {
- payload.addBadge(badge);
- } catch (JSONException e) {
- }
- return payload;
- }
-
-
- /**
- * Create a pre-defined payload with a sound name.
- *
- * @param sound the name of the sound
- * @return a ready-to-send payload
- */
- public static Payload sound(String sound) {
- PushNotificationPayload payload = complex();
- try {
- payload.addSound(sound);
- } catch (JSONException e) {
- }
- return payload;
- }
-
-
- /**
- * Create a pre-defined payload with a simple alert message, a badge and a sound.
- *
- * @param message the alert message
- * @param badge the badge
- * @param sound the name of the sound
- * @return a ready-to-send payload
- */
- public static Payload combined(String message, int badge, String sound) {
- PushNotificationPayload payload = complex();
- try {
- if (message != null) payload.addAlert(message);
- if (badge >= 0) payload.addBadge(badge);
- if (sound != null) payload.addSound(sound);
- } catch (JSONException e) {
- }
- return payload;
- }
-
-
- /**
- * Create an empty payload which you can configure later.
- * This method is usually used to create complex or custom payloads.
- * Note: the payload actually contains the default "aps"
- * dictionary required by APNS.
- *
- * @return a blank payload that can be customized
- */
- public static PushNotificationPayload complex() {
- PushNotificationPayload payload = new PushNotificationPayload();
- return payload;
- }
-
- /* The application Dictionnary */
- private JSONObject apsDictionary;
-
-
- /**
- * Create a default payload with a blank "aps" dictionary.
- */
- public PushNotificationPayload() {
- super();
- this.apsDictionary = new JSONObject();
- try {
- JSONObject payload = getPayload();
- if (!payload.has("aps")) payload.put("aps", this.apsDictionary);
- } catch (JSONException e) {
- e.printStackTrace();
- }
- }
-
-
- /**
- * Create a payload and immediately add an alert message, a badge and a sound.
- *
- * @param alert the alert message
- * @param badge the badge
- * @param sound the name of the sound
- * @throws JSONException
- */
- public PushNotificationPayload(String alert, int badge, String sound) throws JSONException {
- this();
- if (alert != null) addAlert(alert);
- addBadge(badge);
- if (sound != null) addSound(sound);
- }
-
-
- /**
- * Add a badge.
- *
- * @param badge a badge number
- * @throws JSONException
- */
- public void addBadge(int badge) throws JSONException {
- logger.debug("Adding badge [" + badge + "]");
- put("badge", badge, this.apsDictionary, true);
- }
-
-
- /**
- * Add a sound.
- *
- * @param sound the name of a sound
- * @throws JSONException
- */
- public void addSound(String sound) throws JSONException {
- logger.debug("Adding sound [" + sound + "]");
- put("sound", sound, this.apsDictionary, true);
- }
-
-
- /**
- * Add a simple alert message.
- * Note: you cannot add a simple and a custom alert in the same payload.
- *
- * @param alertMessage the alert's message
- * @throws JSONException
- */
- public void addAlert(String alertMessage) throws JSONException {
- String previousAlert = getCompatibleProperty("alert", String.class, "A custom alert (\"%s\") was already added to this payload");
- logger.debug("Adding alert [" + alertMessage + "]" + (previousAlert != null ? " replacing previous alert [" + previousAlert + "]" : ""));
- put("alert", alertMessage, this.apsDictionary, false);
- }
-
-
- /**
- * Get the custom alert object, creating it if it does not yet exist.
- *
- * @return the JSON object defining the custom alert
- * @throws JSONException if a simple alert has already been added to this payload
- */
- private JSONObject getOrAddCustomAlert() throws JSONException {
- JSONObject alert = getCompatibleProperty("alert", JSONObject.class, "A simple alert (\"%s\") was already added to this payload");
- if (alert == null) {
- alert = new JSONObject();
- put("alert", alert, this.apsDictionary, false);
- }
- return alert;
- }
-
-
- /**
- * Get the value of a given property, but only if it is of the expected class.
- * If the value exists but is of a different class than expected, an
- * exception is thrown.
- *
- * This method simply invokes the other getCompatibleProperty method with the root aps dictionary.
- *
- *
- * @param the property value's class
- * @param propertyName the name of the property to get
- * @param expectedClass the property value's expected (required) class
- * @param exceptionMessage the exception message to throw if the value is not of the expected class
- * @return the property's value
- * @throws JSONException
- */
- private T getCompatibleProperty(String propertyName, Class expectedClass, String exceptionMessage) throws JSONException {
- return getCompatibleProperty(propertyName, expectedClass, exceptionMessage, this.apsDictionary);
- }
-
-
- /**
- * Get the value of a given property, but only if it is of the expected class.
- * If the value exists but is of a different class than expected, an
- * exception is thrown.
- *
- * This method is useful for properly supporting properties that can have a simple
- * or complex value (such as "alert")
- *
- * @param the property value's class
- * @param propertyName the name of the property to get
- * @param expectedClass the property value's expected (required) class
- * @param exceptionMessage the exception message to throw if the value is not of the expected class
- * @param dictionary the dictionary where to get the property from
- * @return the property's value
- * @throws JSONException
- */
- @SuppressWarnings("unchecked")
- private T getCompatibleProperty(String propertyName, Class expectedClass, String exceptionMessage, JSONObject dictionary) throws JSONException {
- Object propertyValue = null;
- try {
- propertyValue = dictionary.get(propertyName);
- } catch (Exception e) {
- }
- if (propertyValue == null) return null;
- if (propertyValue.getClass().equals(expectedClass)) return (T) propertyValue;
- try {
- exceptionMessage = String.format(exceptionMessage, propertyValue);
- } catch (Exception e) {
- }
- throw new PayloadAlertAlreadyExistsException(exceptionMessage);
-
- }
-
-
- /**
- * Create a custom alert (if none exist) and add a body to the custom alert.
- *
- * @param body the body of the alert
- * @throws JSONException if the custom alert cannot be added because a simple alert already exists
- */
- public void addCustomAlertBody(String body) throws JSONException {
- put("body", body, getOrAddCustomAlert(), false);
- }
-
-
- /**
- * Create a custom alert (if none exist) and add a custom text for the right button of the popup.
- *
- * @param actionLocKey
- * @throws JSONException if the custom alert cannot be added because a simple alert already exists
- */
- public void addCustomAlertActionLocKey(String actionLocKey) throws JSONException {
- put("action-loc-key", actionLocKey, getOrAddCustomAlert(), false);
- }
-
-
- /**
- * Create a custom alert (if none exist) and add a loc-key parameter.
- *
- * @param locKey
- * @throws JSONException if the custom alert cannot be added because a simple alert already exists
- */
- public void addCustomAlertLocKey(String locKey) throws JSONException {
- put("loc-key", locKey, getOrAddCustomAlert(), false);
- }
-
-
- /**
- * Create a custom alert (if none exist) and add sub-parameters for the loc-key parameter.
- *
- * @param args
- * @throws JSONException if the custom alert cannot be added because a simple alert already exists
- */
- public void addCustomAlertLocArgs(List args) throws JSONException {
- put("loc-args", args, getOrAddCustomAlert(), false);
- }
-
-
- /**
- * Return the maximum payload size in bytes.
- * For APNS payloads, this method returns 256.
- *
- * @return the maximum payload size in bytes (256)
- */
- @Override
- public int getMaximumPayloadSize() {
- return MAXIMUM_PAYLOAD_LENGTH;
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/PushedNotification.java b/javapns/src/main/java/javapns/notification/PushedNotification.java
deleted file mode 100644
index 3ac4135d1..000000000
--- a/javapns/src/main/java/javapns/notification/PushedNotification.java
+++ /dev/null
@@ -1,265 +0,0 @@
-package javapns.notification;
-
-import java.util.*;
-
-import javapns.devices.*;
-
-/**
- * An object representing the result of a push notification to a specific payload to a single device.
- *
- * If Apple's Push Notification Service returned an error-response packet, it is linked to the related PushedNotification
- * so you can find out what the actual error was.
- *
- * @author Sylvain Pedneault
- */
-public class PushedNotification {
-
- private Payload payload;
- private Device device;
- private ResponsePacket response;
-
- private int identifier;
- private long expiry;
- private int transmissionAttempts;
- private boolean transmissionCompleted;
-
- private Exception exception;
-
- protected PushedNotification(Device device, Payload payload) {
- this.device = device;
- this.payload = payload;
- }
-
-
- protected PushedNotification(Device device, Payload payload, int identifier) {
- this.device = device;
- this.payload = payload;
- this.identifier = identifier;
- }
-
-
- /**
- * Returns the payload that was pushed.
- *
- * @return the payload that was pushed
- */
- public Payload getPayload() {
- return payload;
- }
-
-
- protected void setPayload(Payload payload) {
- this.payload = payload;
- }
-
-
- /**
- * Returns the device that the payload was pushed to.
- * @return the device that the payload was pushed to
- */
- public Device getDevice() {
- return device;
- }
-
-
- protected void setDevice(Device device) {
- this.device = device;
- }
-
-
- /**
- * Returns the connection-unique identifier referred to by
- * error-response packets.
- *
- * @return a connection-unique identifier
- */
- public int getIdentifier() {
- return identifier;
- }
-
-
- protected void setIdentifier(int identifier) {
- this.identifier = identifier;
- }
-
-
- /**
- * Returns the expiration date of the push notification.
- *
- * @return the expiration date of the push notification.
- */
- public long getExpiry() {
- return expiry;
- }
-
-
- protected void setExpiry(long expiry) {
- this.expiry = expiry;
- }
-
-
- protected void setTransmissionAttempts(int transmissionAttempts) {
- this.transmissionAttempts = transmissionAttempts;
- }
-
-
- protected void addTransmissionAttempt() {
- transmissionAttempts++;
- }
-
-
- /**
- * Returns the number of attempts that have been made to transmit the notification.
- * @return a number of attempts
- */
- public int getTransmissionAttempts() {
- return transmissionAttempts;
- }
-
-
- /**
- * Returns a human-friendly description of the number of attempts made to transmit the notification.
- * @return a human-friendly description of the number of attempts made to transmit the notification
- */
- public String getLatestTransmissionAttempt() {
- if (transmissionAttempts == 0) return "no attempt yet";
- switch (transmissionAttempts) {
- case 0:
- return "no attempt yet";
- case 1:
- return "first attempt";
- case 2:
- return "second attempt";
- case 3:
- return "third attempt";
- case 4:
- return "fourth attempt";
- default:
- return "attempt #" + transmissionAttempts;
- }
- }
-
-
- protected void setTransmissionCompleted(boolean completed) {
- this.transmissionCompleted = completed;
- }
-
-
- /**
- * Indicates if the notification has been streamed successfully to Apple's server.
- * This does not indicate if an error-response was received or not, but simply
- * that the library successfully completed the transmission of the notification to
- * Apple's server.
- * @return true if the notification was successfully streamed to Apple, false otherwise
- */
- public boolean isTransmissionCompleted() {
- return transmissionCompleted;
- }
-
-
- protected void setResponse(ResponsePacket response) {
- this.response = response;
- }
-
-
- /**
- * If a response packet regarding this notification was received,
- * this method returns it. Otherwise it returns null.
- *
- * @return a response packet, if one was received for this notification
- */
- public ResponsePacket getResponse() {
- return response;
- }
-
-
- /**
- * Returns true if no response packet was received for this notification,
- * or if one was received but is not an error-response (ie command 8),
- * or if one was received but its status is 0 (no error occurred).
- *
- * Returns false if an error-response packet is attached and has
- * a non-zero status code.
- *
- * Make sure you use the Feedback Service to cleanup your list of
- * invalid device tokens, as Apple's documentation says.
- *
- * @return true if push was successful, false otherwise
- */
- public boolean isSuccessful() {
- if (!transmissionCompleted) return false;
- if (response == null) return true;
- if (response.getCommand() != 8) return true;
- if (response.getStatus() == 0) return true;
- return false;
- }
-
-
- /**
- * Filters a list of pushed notifications and returns only the ones that were successful.
- *
- * @param notifications a list of pushed notifications
- * @return a filtered list containing only notifications that were succcessful
- */
- public static List findSuccessfulNotifications(List notifications) {
- List filteredList = new Vector();
- for (PushedNotification notification : notifications) {
- if (notification.isSuccessful()) filteredList.add(notification);
- }
- return filteredList;
- }
-
-
- /**
- * Filters a list of pushed notifications and returns only the ones that failed.
- *
- * @param notifications a list of pushed notifications
- * @return a filtered list containing only notifications that were not successful
- */
- public static List findFailedNotifications(List notifications) {
- List filteredList = new Vector();
- for (PushedNotification notification : notifications) {
- if (!notification.isSuccessful()) {
- filteredList.add(notification);
- }
- }
- return filteredList;
- }
-
-
- /**
- * Returns a human-friendly description of this pushed notification.
- */
- @Override
- public String toString() {
- StringBuilder msg = new StringBuilder();
- msg.append("[" + identifier + "]");
- msg.append(transmissionCompleted ? " transmitted " + payload + " on " + getLatestTransmissionAttempt() : " not transmitted");
- msg.append(" to token " + device.getToken().substring(0, 5) + ".." + device.getToken().substring(59, 64));
- if (response != null) {
- msg.append(" " + response.getMessage());
- }
- return msg.toString();
- }
-
-
- public void updateTo(PushedNotification repushedNotification) {
- // this.setIdentifier(repushedNotification.getIdentifier());
- ResponsePacket newResponse = repushedNotification.getResponse();
- System.out.println(response + " >>> " + newResponse);
- if (newResponse != null) this.setResponse(newResponse);
- this.setTransmissionAttempts(repushedNotification.getTransmissionAttempts());
- this.setTransmissionCompleted(repushedNotification.isTransmissionCompleted());
- }
-
-
- public void setException(Exception exception) {
- this.exception = exception;
- }
-
-
- public Exception getException() {
- return exception;
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/ResponsePacket.java b/javapns/src/main/java/javapns/notification/ResponsePacket.java
deleted file mode 100644
index c717ca846..000000000
--- a/javapns/src/main/java/javapns/notification/ResponsePacket.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package javapns.notification;
-
-/**
- * A response packet, as described in Apple's enhanced notification format.
- *
- * @author Sylvain Pedneault
- */
-public class ResponsePacket {
-
- private int command;
- private int status;
- private int identifier;
-
-
- protected ResponsePacket() {
- }
-
-
- protected ResponsePacket(int command, int status, int identifier) {
- this.command = command;
- this.status = status;
- this.identifier = identifier;
- }
-
-
- protected void linkToPushedNotification(PushNotificationManager notificationManager) {
- PushedNotification notification = null;
- try {
- notification = notificationManager.getPushedNotifications().get(identifier);
- if (notification != null) {
- notification.setResponse(this);
- }
- } catch (Exception e) {
- }
- }
-
-
- /**
- * Returns the response's command number. It should be 8 for all error responses.
- *
- * @return the response's command number (which should be 8)
- */
- public int getCommand() {
- return command;
- }
-
-
- protected void setCommand(int command) {
- this.command = command;
- }
-
-
- /**
- * Returns the response's status code (see getMessage() for a human-friendly status message instead).
- *
- * @return the response's status code
- */
- public int getStatus() {
- return status;
- }
-
-
- protected void setStatus(int status) {
- this.status = status;
- }
-
-
- /**
- * Returns the response's identifier, which matches the pushed notification's.
- *
- * @return the response's identifier
- */
- public int getIdentifier() {
- return identifier;
- }
-
-
- protected void setIdentifier(int identifier) {
- this.identifier = identifier;
- }
-
-
- /**
- * Returns a humand-friendly error message, as documented by Apple.
- *
- * @return a humand-friendly error message
- */
- public String getMessage() {
- if (command == 8) {
- String prefix = "APNS: ["+identifier+"] "; //APNS ERROR FOR MESSAGE ID #" + identifier + ": ";
- if (status == 0) return prefix + "No errors encountered";
- if (status == 1) return prefix + "Processing error";
- if (status == 2) return prefix + "Missing device token";
- if (status == 3) return prefix + "Missing topic";
- if (status == 4) return prefix + "Missing payload";
- if (status == 5) return prefix + "Invalid token size";
- if (status == 6) return prefix + "Invalid topic size";
- if (status == 7) return prefix + "Invalid payload size";
- if (status == 8) return prefix + "Invalid token";
- if (status == 255) return prefix + "None (unknown)";
- return prefix + "Undocumented status code: " + status;
- }
- return "APNS: Undocumented response command: " + command;
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/ResponsePacketReader.java b/javapns/src/main/java/javapns/notification/ResponsePacketReader.java
deleted file mode 100644
index 5af9ed617..000000000
--- a/javapns/src/main/java/javapns/notification/ResponsePacketReader.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package javapns.notification;
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-
-/**
- * Class for reading response packets from an APNS connection.
- * See Apple's documentation on enhanced notification format.
- *
- * @author Sylvain Pedneault
- */
-class ResponsePacketReader {
-
- /* The number of seconds to wait for a response */
- private static final int TIMEOUT = 5 * 1000;
-
-
- /**
- * Read response packets from the current APNS connection and process them.
- *
- * @param notificationManager
- * @return the number of response packets received and processed
- */
- public static int processResponses(PushNotificationManager notificationManager) {
- List responses = readResponses(notificationManager.getActiveSocket());
- handleResponses(responses, notificationManager);
- return responses.size();
- }
-
-
- /**
- * Read raw response packets from the provided socket.
- *
- * Note: this method automatically sets the socket's timeout
- * to TIMEOUT, so not to block the socket's input stream.
- *
- * @param socket
- * @return
- */
- private static List readResponses(Socket socket) {
- List responses = new Vector();
- int previousTimeout = 0;
- try {
- /* Set socket timeout to avoid getting stuck on read() */
- try {
- previousTimeout = socket.getSoTimeout();
- socket.setSoTimeout(TIMEOUT);
- } catch (Exception e) {
- }
- InputStream input = socket.getInputStream();
- while (true) {
- ResponsePacket packet = readResponsePacketData(input);
- if (packet != null) responses.add(packet);
- else break;
- }
-
- } catch (Exception e) {
- /* Ignore exception, as we are expecting timeout exceptions because Apple might not reply anything */
- //System.out.println(e);
- }
- /* Reset socket timeout, just in case */
- try {
- socket.setSoTimeout(previousTimeout);
- } catch (Exception e) {
- }
- //System.out.println("Received "+responses.size()+" response packets");
- return responses;
- }
-
-
- private static void handleResponses(List responses, PushNotificationManager notificationManager) {
- Map envelopes = notificationManager.getPushedNotifications();
- for (ResponsePacket response : responses) {
- response.linkToPushedNotification(notificationManager);
- handleResponse(response, notificationManager);
- }
- }
-
-
- private static ResponsePacket readResponsePacketData(InputStream input) throws IOException {
- int command = input.read();
- if (command < 0) return null;
- int status = input.read();
- if (status < 0) return null;
-
- int identifier_byte1 = input.read();
- if (identifier_byte1 < 0) return null;
- int identifier_byte2 = input.read();
- if (identifier_byte2 < 0) return null;
- int identifier_byte3 = input.read();
- if (identifier_byte3 < 0) return null;
- int identifier_byte4 = input.read();
- if (identifier_byte4 < 0) return null;
- int identifier = (identifier_byte1 << 24) + (identifier_byte2 << 16) + (identifier_byte3 << 8) + (identifier_byte4);
- return new ResponsePacket(command, status, identifier);
- }
-
-
- @Deprecated
- private static void handleResponse(ResponsePacket response, PushNotificationManager notificationManager) {
- //System.out.println("Received response packet: " + response.getMessage());
- if (response.getCommand() == 8) handleErrorResponse(response, notificationManager);
- }
-
-
- @Deprecated
- private static void handleErrorResponse(ResponsePacket response, PushNotificationManager notificationManager) {
- //System.out.println("Received error-response packet: " + response.getMessage());
- // ErrorResponseListener listener = notificationManager.getErrorResponseListener();
- // if (listener != null) {
- // listener.handleError(response, notificationManager);
- // }
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/exceptions/PayloadAlertAlreadyExistsException.java b/javapns/src/main/java/javapns/notification/exceptions/PayloadAlertAlreadyExistsException.java
deleted file mode 100644
index 1249b8633..000000000
--- a/javapns/src/main/java/javapns/notification/exceptions/PayloadAlertAlreadyExistsException.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package javapns.notification.exceptions;
-
-import org.json.*;
-
-/**
- * Thrown when a payload exceeds the maximum size allowed.
- * @author Sylvain Pedneault
- *
- */
-@SuppressWarnings("serial")
-public class PayloadAlertAlreadyExistsException extends JSONException {
-
- /**
- * Default constructor
- */
- public PayloadAlertAlreadyExistsException() {
- super("Payload alert already exists");
- }
-
-
- /**
- * Constructor with custom message
- * @param message
- */
- public PayloadAlertAlreadyExistsException(String message) {
- super(message);
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/exceptions/PayloadMaxSizeExceededException.java b/javapns/src/main/java/javapns/notification/exceptions/PayloadMaxSizeExceededException.java
deleted file mode 100644
index 486d2f792..000000000
--- a/javapns/src/main/java/javapns/notification/exceptions/PayloadMaxSizeExceededException.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package javapns.notification.exceptions;
-
-/**
- * Thrown when a payload exceeds the maximum size allowed.
- * @author Sylvain Pedneault
- *
- */
-@SuppressWarnings("serial")
-public class PayloadMaxSizeExceededException extends Exception {
-
- /**
- * Default constructor
- */
- public PayloadMaxSizeExceededException() {
- super("Total payload size exceeds allowed limit");
- }
-
-
- public PayloadMaxSizeExceededException(int maxSize) {
- super(String.format("Total payload size exceeds allowed limit (%s bytes max)", maxSize));
- }
-
-
- public PayloadMaxSizeExceededException(int maxSize, int currentSize) {
- super(String.format("Total payload size exceeds allowed limit (payload is %s bytes, limit is %s)", currentSize, maxSize));
- }
-
-
- /**
- * Constructor with custom message
- * @param message
- */
- public PayloadMaxSizeExceededException(String message) {
- super(message);
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/exceptions/PayloadMaxSizeProbablyExceededException.java b/javapns/src/main/java/javapns/notification/exceptions/PayloadMaxSizeProbablyExceededException.java
deleted file mode 100644
index 1ec6ca577..000000000
--- a/javapns/src/main/java/javapns/notification/exceptions/PayloadMaxSizeProbablyExceededException.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package javapns.notification.exceptions;
-
-import org.json.*;
-
-/**
- * Thrown when a payload is expected to exceed the maximum size allowed after adding a given property.
- * Invoke payload.setPayloadSizeEstimatedWhenAdding(false) to disable this automatic checking.
- *
- * @author Sylvain Pedneault
- */
-@SuppressWarnings("serial")
-public class PayloadMaxSizeProbablyExceededException extends JSONException {
-
- /**
- * Default constructor
- */
- public PayloadMaxSizeProbablyExceededException() {
- super("Total payload size will most likely exceed allowed limit");
- }
-
-
- public PayloadMaxSizeProbablyExceededException(int maxSize) {
- super(String.format("Total payload size will most likely exceed allowed limit (%s bytes max)", maxSize));
- }
-
-
- public PayloadMaxSizeProbablyExceededException(int maxSize, int estimatedSize) {
- super(String.format("Total payload size will most likely exceed allowed limit (estimated to become %s bytes, limit is %s)", estimatedSize, maxSize));
- }
-
-
- /**
- * Constructor with custom message
- * @param message
- */
- public PayloadMaxSizeProbablyExceededException(String message) {
- super(message);
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/management/APNPayload.java b/javapns/src/main/java/javapns/notification/management/APNPayload.java
deleted file mode 100644
index 61388a6a2..000000000
--- a/javapns/src/main/java/javapns/notification/management/APNPayload.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package javapns.notification.management;
-
-import java.util.*;
-
-import org.json.*;
-
-/**
- * An MDM payload for APN (Access Point Name).
- *
- * @author Sylvain Pedneault
- */
-public class APNPayload extends MobileConfigPayload {
-
- public APNPayload(int payloadVersion, String payloadOrganization, String payloadIdentifier, String payloadDisplayName, Map defaultsData, String defaultsDomainName, Map[] apns, String apn, String username) throws JSONException {
- super(payloadVersion, "com.apple.apn.managed", payloadOrganization, payloadIdentifier, payloadDisplayName);
- JSONObject payload = getPayload();
- payload.put("DefaultsData", defaultsData);
- payload.put("defaultsDomainName", defaultsDomainName);
- for (Map apnsEntry : apns)
- payload.put("apns", apnsEntry);
- payload.put("apn", apn);
- payload.put("username", username);
- }
-
-
- public void setPassword(APNPayload value) throws JSONException {
- getPayload().put("password", value);
- }
-
-
- public void setProxy(String value) throws JSONException {
- getPayload().put("proxy", value);
- }
-
-
- public void setProxyPort(int value) throws JSONException {
- getPayload().put("proxyPort", value);
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/management/CalDAVPayload.java b/javapns/src/main/java/javapns/notification/management/CalDAVPayload.java
deleted file mode 100644
index 8d6e90fd8..000000000
--- a/javapns/src/main/java/javapns/notification/management/CalDAVPayload.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package javapns.notification.management;
-
-import org.json.*;
-
-/**
- * An MDM payload for CalDAV.
- *
- * @author Sylvain Pedneault
- */
-public class CalDAVPayload extends MobileConfigPayload {
-
- public CalDAVPayload(int payloadVersion, String payloadOrganization, String payloadIdentifier, String payloadDisplayName, String calDAVHostName, String calDAVUsername, boolean calDAVUseSSL) throws JSONException {
- super(payloadVersion, "com.apple.caldav.account", payloadOrganization, payloadIdentifier, payloadDisplayName);
- JSONObject payload = getPayload();
- payload.put("CalDAVHostName", calDAVHostName);
- payload.put("CalDAVUsername", calDAVUsername);
- payload.put("CalDAVUseSSL", calDAVUseSSL);
- }
-
-
- public void setCalDAVAccountDescription(String value) throws JSONException {
- getPayload().put("CalDAVAccountDescription", value);
- }
-
-
- public void setCalDAVPassword(String value) throws JSONException {
- getPayload().put("CalDAVPassword", value);
- }
-
-
- public void setCalDAVPort(int value) throws JSONException {
- getPayload().put("CalDAVPort", value);
- }
-
-
- public void setCalDAVPrincipalURL(String value) throws JSONException {
- getPayload().put("CalDAVPrincipalURL", value);
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/management/CalendarSubscriptionPayload.java b/javapns/src/main/java/javapns/notification/management/CalendarSubscriptionPayload.java
deleted file mode 100644
index db91a801a..000000000
--- a/javapns/src/main/java/javapns/notification/management/CalendarSubscriptionPayload.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package javapns.notification.management;
-
-import org.json.*;
-
-/**
- * An MDM payload for CalendarSubscription.
- *
- * @author Sylvain Pedneault
- */
-public class CalendarSubscriptionPayload extends MobileConfigPayload {
-
- public CalendarSubscriptionPayload(int payloadVersion, String payloadOrganization, String payloadIdentifier, String payloadDisplayName, String subCalAccountHostName, boolean subCalAccountUseSSL) throws JSONException {
- super(payloadVersion, "com.apple.caldav.account", payloadOrganization, payloadIdentifier, payloadDisplayName);
- JSONObject payload = getPayload();
- payload.put("SubCalAccountHostName", subCalAccountHostName);
- payload.put("SubCalAccountUseSSL", subCalAccountUseSSL);
- }
-
-
- public void setSubCalAccountDescription(String value) throws JSONException {
- getPayload().put("SubCalAccountDescription", value);
- }
-
-
- public void setSubCalAccountUsername(String value) throws JSONException {
- getPayload().put("SubCalAccountUsername", value);
- }
-
-
- public void setSubCalAccountPassword(String value) throws JSONException {
- getPayload().put("SubCalAccountPassword", value);
- }
-
-
- public void setSubCalAccountUseSSL(boolean value) throws JSONException {
- getPayload().put("SubCalAccountUseSSL", value);
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/management/EmailPayload.java b/javapns/src/main/java/javapns/notification/management/EmailPayload.java
deleted file mode 100644
index d0fd2d593..000000000
--- a/javapns/src/main/java/javapns/notification/management/EmailPayload.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package javapns.notification.management;
-
-import org.json.*;
-
-/**
- * An MDM payload for Email.
- *
- * @author Sylvain Pedneault
- */
-public class EmailPayload extends MobileConfigPayload {
-
- public EmailPayload(int payloadVersion, String payloadOrganization, String payloadIdentifier, String payloadDisplayName, String emailAccountType, String emailAddress, String incomingMailServerAuthentication, String incomingMailServerHostName, String incomingMailServerUsername, String outgoingMailServerAuthentication, String outgoingMailServerHostName, String outgoingMailServerUsername) throws JSONException {
- super(payloadVersion, "com.apple.mail.managed", payloadOrganization, payloadIdentifier, payloadDisplayName);
- JSONObject payload = getPayload();
- payload.put("EmailAccountType", emailAccountType);
- payload.put("EmailAddress", emailAddress);
- payload.put("IncomingMailServerAuthentication", incomingMailServerAuthentication);
- payload.put("IncomingMailServerHostName", incomingMailServerHostName);
- payload.put("IncomingMailServerUsername", incomingMailServerUsername);
- payload.put("OutgoingMailServerAuthentication", outgoingMailServerAuthentication);
- payload.put("OutgoingMailServerHostName", outgoingMailServerHostName);
- payload.put("OutgoingMailServerUsername", outgoingMailServerUsername);
- }
-
-
- public void setEmailAccountDescription(String value) throws JSONException {
- getPayload().put("EmailAccountDescription", value);
- }
-
-
- public void setEmailAccountName(String value) throws JSONException {
- getPayload().put("EmailAccountName", value);
- }
-
-
- public void setIncomingMailServerPortNumber(int value) throws JSONException {
- getPayload().put("IncomingMailServerPortNumber", value);
- }
-
-
- public void setIncomingMailServerUseSSL(boolean value) throws JSONException {
- getPayload().put("IncomingMailServerUseSSL", value);
- }
-
-
- public void setIncomingPassword(String value) throws JSONException {
- getPayload().put("IncomingPassword", value);
- }
-
-
- public void setOutgoingPassword(String value) throws JSONException {
- getPayload().put("OutgoingPassword", value);
- }
-
-
- public void setOutgoingPasswwordSameAsIncomingPassword(boolean value) throws JSONException {
- getPayload().put("OutgoingPasswwordSameAsIncomingPassword", value);
- }
-
-
- public void setOutgoingMailServerPortNumber(int value) throws JSONException {
- getPayload().put("OutgoingMailServerPortNumber", value);
- }
-
-
- public void setOutgoingMailServerUseSSL(boolean value) throws JSONException {
- getPayload().put("OutgoingMailServerUseSSL", value);
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/management/LDAPPayload.java b/javapns/src/main/java/javapns/notification/management/LDAPPayload.java
deleted file mode 100644
index 651f1a5b8..000000000
--- a/javapns/src/main/java/javapns/notification/management/LDAPPayload.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package javapns.notification.management;
-
-import org.json.*;
-
-/**
- * An MDM payload for LDAP.
- *
- * @author Sylvain Pedneault
- */
-public class LDAPPayload extends MobileConfigPayload {
-
- public LDAPPayload(int payloadVersion, String payloadOrganization, String payloadIdentifier, String payloadDisplayName, String ldapAccountHostName, boolean ldapAccountUseSSL) throws JSONException {
- super(payloadVersion, "com.apple.webClip.managed", payloadOrganization, payloadIdentifier, payloadDisplayName);
- JSONObject payload = getPayload();
- payload.put("LDAPAccountHostName", ldapAccountHostName);
- payload.put("LDAPAccountUseSSL", ldapAccountUseSSL);
- }
-
-
- public void setLDAPAccountDescription(boolean value) throws JSONException {
- getPayload().put("LDAPAccountDescription", value);
- }
-
-
- public void setLDAPAccountUserName(boolean value) throws JSONException {
- getPayload().put("LDAPAccountUserName", value);
- }
-
-
- public void setLDAPAccountPassword(boolean value) throws JSONException {
- getPayload().put("LDAPAccountPassword", value);
- }
-
-
- public JSONObject addSearchSettings(String ldapSearchSettingSearchBase, String ldapSearchSettingScope) throws JSONException {
- return addSearchSettings(ldapSearchSettingSearchBase, ldapSearchSettingScope, null);
- }
-
-
- public JSONObject addSearchSettings(String ldapSearchSettingSearchBase, int ldapSearchSettingScope) throws JSONException {
- return addSearchSettings(ldapSearchSettingSearchBase, ldapSearchSettingScope, null);
- }
-
-
- public JSONObject addSearchSettings(String ldapSearchSettingSearchBase, int ldapSearchSettingScope, String ldapSearchSettingDescription) throws JSONException {
- return addSearchSettings(ldapSearchSettingSearchBase, ldapSearchSettingScope == 0 ? "LDAPSearchSettingScopeBase" : ldapSearchSettingScope == 1 ? "LDAPSearchSettingScopeBase" : "LDAPSearchSettingScopeSubtree", ldapSearchSettingDescription);
- }
-
-
- public JSONObject addSearchSettings(String ldapSearchSettingSearchBase, String ldapSearchSettingScope, String ldapSearchSettingDescription) throws JSONException {
- JSONObject payload = getPayload();
- JSONObject searchSettings = new JSONObject();
- payload.put("LDAPSearchSettings", searchSettings);
- searchSettings.put("LDAPSearchSettingSearchBase", ldapSearchSettingSearchBase);
- searchSettings.put("LDAPSearchSettingScope", ldapSearchSettingScope);
- if (ldapSearchSettingDescription != null) searchSettings.put("LDAPSearchSettingDescription", ldapSearchSettingDescription);
- return searchSettings;
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/management/MobileConfigPayload.java b/javapns/src/main/java/javapns/notification/management/MobileConfigPayload.java
deleted file mode 100644
index 1dcb40b0d..000000000
--- a/javapns/src/main/java/javapns/notification/management/MobileConfigPayload.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package javapns.notification.management;
-
-import javapns.notification.*;
-
-import org.json.*;
-
-/**
- * A payload template compatible with Apple Mobile Device Management's Config Payload specification (beta version).
- *
- * @author Sylvain Pedneault
- */
-public abstract class MobileConfigPayload extends Payload {
-
- private static long serialuuid = 10000000;
-
-
- private static String generateUUID() {
- return System.nanoTime() + "." + (++serialuuid);
- }
-
-
- public MobileConfigPayload(int payloadVersion, String payloadType, String payloadOrganization, String payloadIdentifier, String payloadDisplayName) throws JSONException {
- this(payloadVersion, generateUUID(), payloadType, payloadOrganization, payloadIdentifier, payloadDisplayName);
- }
-
-
- public MobileConfigPayload(int payloadVersion, String payloadUUID, String payloadType, String payloadOrganization, String payloadIdentifier, String payloadDisplayName) throws JSONException {
- super();
- JSONObject payload = getPayload();
- payload.put("PayloadVersion", payloadVersion);
- payload.put("PayloadUUID", payloadUUID);
- payload.put("PayloadType", payloadType);
- payload.put("PayloadOrganization", payloadOrganization);
- payload.put("PayloadIdentifier", payloadIdentifier);
- payload.put("PayloadDisplayName", payloadDisplayName);
- }
-
-
- public void setPayloadDescription(String description) throws JSONException {
- getPayload().put("PayloadDescription", description);
- }
-
-
- public void setPayloadRemovalDisallowed(boolean disallowed) throws JSONException {
- getPayload().put("PayloadRemovalDisallowed", disallowed);
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/management/PasswordPolicyPayload.java b/javapns/src/main/java/javapns/notification/management/PasswordPolicyPayload.java
deleted file mode 100644
index 0f755be14..000000000
--- a/javapns/src/main/java/javapns/notification/management/PasswordPolicyPayload.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package javapns.notification.management;
-
-import org.json.*;
-
-/**
- * An MDM payload for PasswordPolicy.
- *
- * @author Sylvain Pedneault
- */
-public class PasswordPolicyPayload extends MobileConfigPayload {
-
- public PasswordPolicyPayload(int payloadVersion, String payloadOrganization, String payloadIdentifier, String payloadDisplayName) throws JSONException {
- super(payloadVersion, "com.apple.mobiledevice.passwordpolicy", payloadOrganization, payloadIdentifier, payloadDisplayName);
- }
-
-
- public void setAllowSimple(boolean value) throws JSONException {
- getPayload().put("allowSimple", value);
- }
-
-
- public void setForcePIN(boolean value) throws JSONException {
- getPayload().put("forcePIN", value);
- }
-
-
- public void setMaxFailedAttempts(int value) throws JSONException {
- getPayload().put("maxFailedAttempts", value);
- }
-
-
- public void setMaxInactivity(int value) throws JSONException {
- getPayload().put("maxInactivity", value);
- }
-
-
- public void setMaxPINAgeInDays(int value) throws JSONException {
- getPayload().put("maxPINAgeInDays", value);
- }
-
-
- public void setMinComplexChars(int value) throws JSONException {
- getPayload().put("minComplexChars", value);
- }
-
-
- public void setMinLength(int value) throws JSONException {
- getPayload().put("minLength", value);
- }
-
-
- public void setRequireAlphanumeric(boolean value) throws JSONException {
- getPayload().put("requireAlphanumeric", value);
- }
-
-
- public void setPinHistory(int value) throws JSONException {
- getPayload().put("pinHistory", value);
- }
-
-
- public void setManualFetchingWhenRoaming(boolean value) throws JSONException {
- getPayload().put("manualFetchingWhenRoaming", value);
- }
-
-
- public void setMaxGracePeriod(int value) throws JSONException {
- getPayload().put("maxGracePeriod", value);
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/management/RemovalPasswordPayload.java b/javapns/src/main/java/javapns/notification/management/RemovalPasswordPayload.java
deleted file mode 100644
index 9fc987a94..000000000
--- a/javapns/src/main/java/javapns/notification/management/RemovalPasswordPayload.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package javapns.notification.management;
-
-import org.json.*;
-
-/**
- * An MDM payload for RemovalPassword.
- *
- * @author Sylvain Pedneault
- */
-public class RemovalPasswordPayload extends MobileConfigPayload {
-
- public RemovalPasswordPayload(int payloadVersion, String payloadOrganization, String payloadIdentifier, String payloadDisplayName) throws JSONException {
- super(payloadVersion, "com.apple.profileRemovalPassword", payloadOrganization, payloadIdentifier, payloadDisplayName);
- }
-
-
- public void setRemovalPasword(String value) throws JSONException {
- getPayload().put("RemovalPassword", value);
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/management/RestrictionsPayload.java b/javapns/src/main/java/javapns/notification/management/RestrictionsPayload.java
deleted file mode 100644
index 4e187b24b..000000000
--- a/javapns/src/main/java/javapns/notification/management/RestrictionsPayload.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package javapns.notification.management;
-
-import org.json.*;
-
-/**
- * An MDM payload for Restrictions.
- *
- * @author Sylvain Pedneault
- */
-public class RestrictionsPayload extends MobileConfigPayload {
-
- public RestrictionsPayload(int payloadVersion, String payloadOrganization, String payloadIdentifier, String payloadDisplayName) throws JSONException {
- super(payloadVersion, "com.apple.applicationaccess", payloadOrganization, payloadIdentifier, payloadDisplayName);
- }
-
-
- public void setAllowAppInstallation(boolean value) throws JSONException {
- getPayload().put("allowAppInstallation", value);
- }
-
-
- public void setAllowCamera(boolean value) throws JSONException {
- getPayload().put("allowCamera", value);
- }
-
-
- public void setAllowExplicitContent(boolean value) throws JSONException {
- getPayload().put("allowExplicitContent", value);
- }
-
-
- public void setAllowScreenShot(boolean value) throws JSONException {
- getPayload().put("allowScreenShot", value);
- }
-
-
- public void setAllowYouTube(boolean value) throws JSONException {
- getPayload().put("allowYouTube", value);
- }
-
-
- public void setAllowiTunes(boolean value) throws JSONException {
- getPayload().put("allowAppInstallation", value);
- }
-
-
- public void setAllowSafari(boolean value) throws JSONException {
- getPayload().put("allowSafari", value);
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/management/SCEPPayload.java b/javapns/src/main/java/javapns/notification/management/SCEPPayload.java
deleted file mode 100644
index 32b9b1a3b..000000000
--- a/javapns/src/main/java/javapns/notification/management/SCEPPayload.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package javapns.notification.management;
-
-import java.util.*;
-
-import org.json.*;
-
-/**
- * An MDM payload for SCEP (Simple Certificate Enrollment Protocol).
- *
- * @author Sylvain Pedneault
- */
-public class SCEPPayload extends MobileConfigPayload {
-
- public SCEPPayload(int payloadVersion, String payloadOrganization, String payloadIdentifier, String payloadDisplayName, String url) throws JSONException {
- super(payloadVersion, "com.apple.encrypted-profile-service", payloadOrganization, payloadIdentifier, payloadDisplayName);
- JSONObject payload = getPayload();
- payload.put("URL", url);
- }
-
-
- public void setName(String value) throws JSONException {
- getPayload().put("Name", value);
- }
-
-
- public void setSubject(String value) throws JSONException {
- String[] parts = value.split("/");
- List list = new ArrayList();
- for (String part : parts) {
- String[] subparts = value.split("=");
- list.add(subparts);
- }
- String[][] subject = list.toArray(new String[0][0]);
- setSubject(subject);
- }
-
-
- public void setSubject(String[][] value) throws JSONException {
- getPayload().put("Subject", value);
- }
-
-
- public void setChallenge(String value) throws JSONException {
- getPayload().put("Challenge", value);
- }
-
-
- public void setKeysize(int value) throws JSONException {
- getPayload().put("Keysize", value);
- }
-
-
- public void setKeyType(String value) throws JSONException {
- getPayload().put("Key Type", value);
- }
-
-
- public void setKeyUsage(int value) throws JSONException {
- getPayload().put("Key Usage", value);
- }
-
-
- public JSONObject addSubjectAltName() throws JSONException {
- JSONObject object = new JSONObject();
- getPayload().put("SubjectAltName", object);
- return object;
- }
-
-
- public JSONObject addGetCACaps() throws JSONException {
- JSONObject object = new JSONObject();
- getPayload().put("GetCACaps", object);
- return object;
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/management/VPNPayload.java b/javapns/src/main/java/javapns/notification/management/VPNPayload.java
deleted file mode 100644
index f9535ba1e..000000000
--- a/javapns/src/main/java/javapns/notification/management/VPNPayload.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package javapns.notification.management;
-
-import org.json.*;
-
-/**
- * An MDM payload for VPN.
- *
- * @author Sylvain Pedneault
- */
-public class VPNPayload extends MobileConfigPayload {
-
- public static final String VPNTYPE_L2TP = "L2TP";
- public static final String VPNTYPE_PPTP = "PPTP";
- public static final String VPNTYPE_IPSec = "IPSec";
-
-
- public VPNPayload(int payloadVersion, String payloadOrganization, String payloadIdentifier, String payloadDisplayName, String userDefinedName, boolean overridePrimary, String vpnType) throws JSONException {
- super(payloadVersion, "com.apple.vpn.managed", payloadOrganization, payloadIdentifier, payloadDisplayName);
- JSONObject payload = getPayload();
- payload.put("UserDefinedName", userDefinedName);
- payload.put("OverridePrimary", overridePrimary);
- payload.put("VPNType", vpnType);
- }
-
-
- public JSONObject addPPP() throws JSONException {
- JSONObject object = new JSONObject();
- getPayload().put("PPP", object);
- return object;
- }
-
-
- public JSONObject addIPSec() throws JSONException {
- JSONObject object = new JSONObject();
- getPayload().put("IPSec", object);
- return object;
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/management/WebClipPayload.java b/javapns/src/main/java/javapns/notification/management/WebClipPayload.java
deleted file mode 100644
index 4b191db79..000000000
--- a/javapns/src/main/java/javapns/notification/management/WebClipPayload.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package javapns.notification.management;
-
-import org.json.*;
-
-/**
- * An MDM payload for WebClip.
- *
- * @author Sylvain Pedneault
- */
-public class WebClipPayload extends MobileConfigPayload {
-
- public WebClipPayload(int payloadVersion, String payloadOrganization, String payloadIdentifier, String payloadDisplayName, String url, String label) throws JSONException {
- super(payloadVersion, "com.apple.webClip.managed", payloadOrganization, payloadIdentifier, payloadDisplayName);
- JSONObject payload = getPayload();
- payload.put("URL", url);
- payload.put("Label", label);
- }
-
-
- public void setIcon(Object data) throws JSONException {
- getPayload().put("Icon", data);
- }
-
-
- public void setIsRemovable(boolean value) throws JSONException {
- getPayload().put("IsRemovable", value);
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/management/WiFiPayload.java b/javapns/src/main/java/javapns/notification/management/WiFiPayload.java
deleted file mode 100644
index 038683363..000000000
--- a/javapns/src/main/java/javapns/notification/management/WiFiPayload.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package javapns.notification.management;
-
-import org.json.*;
-
-/**
- * An MDM payload for Wi-Fi.
- *
- * @author Sylvain Pedneault
- */
-public class WiFiPayload extends MobileConfigPayload {
-
- public WiFiPayload(int payloadVersion, String payloadOrganization, String payloadIdentifier, String payloadDisplayName, String SSID_STR, boolean hiddenNetwork, String encryptionType) throws JSONException {
- super(payloadVersion, "com.apple.wifi.managed", payloadOrganization, payloadIdentifier, payloadDisplayName);
- JSONObject payload = getPayload();
- payload.put("SSID_STR", SSID_STR);
- payload.put("HIDDEN_NETWORK", hiddenNetwork);
- payload.put("EncryptionType", encryptionType);
- }
-
-
- public void setPassword(String value) throws JSONException {
- getPayload().put("Password", value);
- }
-
-
- public JSONObject addEAPClientConfiguration() throws JSONException {
- JSONObject object = new JSONObject();
- getPayload().put("EAPClientConfiguration", object);
- return object;
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/transmission/NotificationProgressListener.java b/javapns/src/main/java/javapns/notification/transmission/NotificationProgressListener.java
deleted file mode 100644
index 30ea436dd..000000000
--- a/javapns/src/main/java/javapns/notification/transmission/NotificationProgressListener.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package javapns.notification.transmission;
-
-/**
- * An event listener for monitoring progress of NotificationThreads
- *
- * @author Sylvain Pedneault
- */
-public interface NotificationProgressListener {
-
- public void eventAllThreadsStarted(NotificationThreads notificationThreads);
-
-
- public void eventThreadStarted(NotificationThread notificationThread);
-
-
- public void eventThreadFinished(NotificationThread notificationThread);
-
-
- public void eventConnectionRestarted(NotificationThread notificationThread);
-
-
- public void eventAllThreadsFinished(NotificationThreads notificationThreads);
-
-}
diff --git a/javapns/src/main/java/javapns/notification/transmission/NotificationThread.java b/javapns/src/main/java/javapns/notification/transmission/NotificationThread.java
deleted file mode 100644
index ceda2efa6..000000000
--- a/javapns/src/main/java/javapns/notification/transmission/NotificationThread.java
+++ /dev/null
@@ -1,277 +0,0 @@
-package javapns.notification.transmission;
-
-import java.util.*;
-
-import javapns.devices.*;
-import javapns.notification.*;
-
-/**
- * Pushes a payload to a large number of devices in a single separate thread
- *
- * No more than {@code maxNotificationsPerConnection} are pushed over a single connection.
- * When that maximum is reached, the connection is restarted automatically and push continues.
- * This is intended to avoid an undocumented notification-per-connection limit observed
- * occasionnally with Apple servers.
- *
- * Usage: once a NotificationThread is created, invoke {@code start()} to push the payload to all devices in a separate thread.
- *
- * To run this code unthreaded, invoke {@code run()} directly (rarely used).
- *
- * @author Sylvain Pedneault
- */
-public class NotificationThread extends Thread {
-
- private static final int DEFAULT_MAXNOTIFICATIONSPERCONNECTION = 200;
-
- private PushNotificationManager notificationManager;
- private AppleNotificationServer server;
- private Payload payload;
- private List devices;
- private int maxNotificationsPerConnection = DEFAULT_MAXNOTIFICATIONSPERCONNECTION;
- private long sleepBetweenNotifications = 0;
- private NotificationProgressListener listener;
- private int threadNumber = 1;
- private int nextMessageIdentifier = 1;
- private List notifications = new Vector();
-
-
- /**
- * Create a grouped thread for pushing notifications to a list of devices
- * and coordinating with a parent NotificationThreads object.
- *
- * @param threads
- * @param notificationManager
- * @param server
- * @param payload
- * @param devices
- */
- public NotificationThread(NotificationThreads threads, PushNotificationManager notificationManager, AppleNotificationServer server, Payload payload, List devices) {
- super(threads, "javapns notification thread (" + devices.size() + ")");
- this.notificationManager = notificationManager == null ? new PushNotificationManager() : notificationManager;
- this.server = server;
- this.payload = payload;
- this.devices = devices;
- }
-
-
- /**
- * Create a grouped thread for pushing notifications to an array of devices
- * and coordinating with a parent NotificationThreads object.
- *
- * @param threads
- * @param notificationManager
- * @param server
- * @param payload
- * @param devices
- */
- public NotificationThread(NotificationThreads threads, PushNotificationManager notificationManager, AppleNotificationServer server, Payload payload, Device... devices) {
- this(threads, notificationManager, server, payload, Arrays.asList(devices));
- }
-
-
- /**
- * Create a standalone thread for pushing notifications to a list of devices.
- *
- * @param notificationManager
- * @param server
- * @param payload
- * @param devices
- */
- public NotificationThread(PushNotificationManager notificationManager, AppleNotificationServer server, Payload payload, List devices) {
- this(null, notificationManager, server, payload, devices);
- }
-
-
- /**
- * Create a standalone thread for pushing notifications to an array of devices.
- *
- * @param notificationManager
- * @param server
- * @param payload
- * @param devices
- */
- public NotificationThread(PushNotificationManager notificationManager, AppleNotificationServer server, Payload payload, Device... devices) {
- this(notificationManager, server, payload, Arrays.asList(devices));
- }
-
-
- public void run() {
- int total = devices.size();
- if (listener != null) listener.eventThreadStarted(this);
- try {
- notificationManager.initializeConnection(server);
- for (int i = 0; i < total; i++) {
- Device device = devices.get(i);
- int message = newMessageIdentifier();
- PushedNotification notification = notificationManager.sendNotification(device, payload, false, message);
- notifications.add(notification);
- if (sleepBetweenNotifications > 0) sleep(sleepBetweenNotifications);
- if (i != 0 && i % maxNotificationsPerConnection == 0) {
- if (listener != null) listener.eventConnectionRestarted(this);
- notificationManager.restartConnection(server);
- }
- }
- notificationManager.stopConnection();
- } catch (Exception e) {
- e.printStackTrace();
- }
- if (listener != null) listener.eventThreadFinished(this);
- /* Also notify the parent NotificationThreads, so that it can determine when all threads have finished working */
- if (getThreadGroup() instanceof NotificationThreads) ((NotificationThreads) getThreadGroup()).threadFinished(this);
- }
-
-
- /**
- * Set a maximum number of notifications that should be streamed over a continuous connection
- * to an Apple server. When that maximum is reached, the thread automatically closes and
- * reopens a fresh new connection to the server and continues streaming notifications.
- *
- * Default is 200 (recommended).
- *
- * @param maxNotificationsPerConnection
- */
- public void setMaxNotificationsPerConnection(int maxNotificationsPerConnection) {
- this.maxNotificationsPerConnection = maxNotificationsPerConnection;
- }
-
-
- public int getMaxNotificationsPerConnection() {
- return maxNotificationsPerConnection;
- }
-
-
- /**
- * Set a delay the thread should sleep between each notification.
- * This is sometimes useful when communication with Apple servers is
- * unreliable and notifications are streaming too fast.
- *
- * Default is 0.
- *
- * @param milliseconds
- */
- public void setSleepBetweenNotifications(long milliseconds) {
- this.sleepBetweenNotifications = milliseconds;
- }
-
-
- public long getSleepBetweenNotifications() {
- return sleepBetweenNotifications;
- }
-
-
- public void setDevices(List devices) {
- this.devices = devices;
- }
-
-
- public List getDevices() {
- return devices;
- }
-
-
- /**
- * Get the number of devices that this thread pushes to.
- *
- * @return the number of devices registered with this thread
- */
- public int size() {
- return devices.size();
- }
-
-
- /**
- * Provide an event listener which will be notified of this thread's progress.
- *
- * @param listener any object implementing the NotificationProgressListener interface
- */
- public void setListener(NotificationProgressListener listener) {
- this.listener = listener;
- }
-
-
- public NotificationProgressListener getListener() {
- return listener;
- }
-
-
- /**
- * Set the thread number so that generated message identifiers can be made
- * unique across all threads.
- *
- * @param threadNumber
- */
- protected void setThreadNumber(int threadNumber) {
- this.threadNumber = threadNumber;
- }
-
-
- /**
- * Return the thread number assigned by the parent NotificationThreads object, if any.
- *
- * @return the unique number assigned to this thread by the parent group
- */
- public int getThreadNumber() {
- return threadNumber;
- }
-
-
- /**
- * Return a new sequential message identifier.
- *
- * @return a message identifier unique to all NotificationThread objects
- */
- public int newMessageIdentifier() {
- return (threadNumber << 24) | nextMessageIdentifier++;
- }
-
-
- /**
- * Returns the first message identifier generated by this thread.
- *
- * @return a message identifier unique to all NotificationThread objects
- */
- public int getFirstMessageIdentifier() {
- return (threadNumber << 24) | 1;
- }
-
-
- /**
- * Returns the last message identifier generated by this thread.
- *
- * @return a message identifier unique to all NotificationThread objects
- */
- public int getLastMessageIdentifier() {
- return (threadNumber << 24) | devices.size();
- }
-
-
- /**
- * Returns list of all notifications pushed by this thread (successful or not).
- *
- * @return a list of pushed notifications
- */
- public List getPushedNotifications() {
- return notifications;
- }
-
-
- /**
- * Returns list of all notifications that this thread attempted to push but that failed.
- *
- * @return a list of failed notifications
- */
- public List getFailedNotifications() {
- return PushedNotification.findFailedNotifications(getPushedNotifications());
- }
-
-
- /**
- * Returns list of all notifications that this thread attempted to push and succeeded.
- *
- * @return a list of failed notifications
- */
- public List getSuccessfulNotifications() {
- return PushedNotification.findSuccessfulNotifications(getPushedNotifications());
- }
-
-}
diff --git a/javapns/src/main/java/javapns/notification/transmission/NotificationThreads.java b/javapns/src/main/java/javapns/notification/transmission/NotificationThreads.java
deleted file mode 100644
index 608477e6a..000000000
--- a/javapns/src/main/java/javapns/notification/transmission/NotificationThreads.java
+++ /dev/null
@@ -1,315 +0,0 @@
-package javapns.notification.transmission;
-
-import java.util.*;
-
-import javapns.devices.*;
-import javapns.notification.*;
-
-/**
- * Pushes a payload to a large number of devices using multiple threads
- *
- * The list of devices is spread evenly into multiple {@link javapns.notification.transmission.NotificationThread}s.
- *
- * Usage: once a NotificationThreads is created, invoke {@code start()} to start all {@link javapns.notification.transmission.NotificationThread} threads.
- * You can provide a {@link javapns.notification.transmission.NotificationProgressListener} to receive events about the work being done.
-
- * @author Sylvain Pedneault
- */
-public class NotificationThreads extends ThreadGroup {
-
- private List threads = new Vector();
- private NotificationProgressListener listener;
- private int threadsRunning = 0;
- private Object finishPoint = new Object();
-
-
- /**
- * Create the specified number of notification threads and spread the devices evenly between the threads.
- *
- * @param server the server to push to
- * @param payload the payload to push
- * @param devices a very large list of devices
- * @param numberOfThreads the number of threads to create to share the work
- */
- public NotificationThreads(AppleNotificationServer server, Payload payload, List devices, int numberOfThreads) {
- super("javapns notification threads (" + numberOfThreads + " threads)");
- for (List deviceGroup : groupDevices(devices, numberOfThreads))
- threads.add(new NotificationThread(this, new PushNotificationManager(), server, payload, deviceGroup));
- }
-
-
- /**
- * Create the specified number of notification threads and spread the devices evenly between the threads.
- * Internally, this constructor uses a AppleNotificationServerBasicImpl to encapsulate the provided keystore, password and production parameters.
- *
- * @param keystore the keystore to use (can be a File, an InputStream, a String for a file path, or a byte[] array)
- * @param password the keystore's password
- * @param production true to use Apple's production servers, false to use the sandbox
- * @param payload the payload to push
- * @param devices a very large list of devices
- * @param numberOfThreads the number of threads to create to share the work
- * @throws Exception
- */
- public NotificationThreads(Object keystore, String password, boolean production, Payload payload, List devices, int numberOfThreads) throws Exception {
- this(new AppleNotificationServerBasicImpl(keystore, password, production), payload, devices, numberOfThreads);
- }
-
-
- /**
- * Spread the devices evenly between the provided threads.
- *
- * @param server the server to push to
- * @param payload the payload to push
- * @param devices a very large list of devices
- * @param threads a list of pre-built threads
- */
- public NotificationThreads(AppleNotificationServer server, Payload payload, List devices, List threads) {
- super("javapns notification threads (" + threads.size() + " threads)");
- this.threads = threads;
- List> groups = groupDevices(devices, threads.size());
- for (int i = 0; i < groups.size(); i++)
- threads.get(i).setDevices(groups.get(i));
- }
-
-
- /**
- * Spread the devices evenly between the provided threads.
- * Internally, this constructor uses a AppleNotificationServerBasicImpl to encapsulate the provided keystore, password and production parameters.
- *
- * @param keystore the keystore to use (can be a File, an InputStream, a String for a file path, or a byte[] array)
- * @param password the keystore's password
- * @param production true to use Apple's production servers, false to use the sandbox
- * @param payload the payload to push
- * @param devices a very large list of devices
- * @param threads a list of pre-built threads
- * @throws Exception
- */
- public NotificationThreads(Object keystore, String password, boolean production, Payload payload, List devices, List threads) throws Exception {
- this(new AppleNotificationServerBasicImpl(keystore, password, production), payload, devices, threads);
- }
-
-
- /**
- * Use the provided threads which should already each have their group of devices to work with.
- *
- * @param server the server to push to
- * @param payload the payload to push
- * @param threads a list of pre-built threads
- */
- public NotificationThreads(AppleNotificationServer server, Payload payload, List threads) {
- super("javapns notification threads (" + threads.size() + " threads)");
- this.threads = threads;
- }
-
-
- /**
- * Use the provided threads which should already each have their group of devices to work with.
- * Internally, this constructor uses a AppleNotificationServerBasicImpl to encapsulate the provided keystore, password and production parameters.
- *
- * @param keystore the keystore to use (can be a File, an InputStream, a String for a file path, or a byte[] array)
- * @param password the keystore's password
- * @param production true to use Apple's production servers, false to use the sandbox
- * @param payload the payload to push
- * @param threads a list of pre-built threads
- * @throws Exception
- */
- public NotificationThreads(Object keystore, String password, boolean production, Payload payload, List threads) throws Exception {
- this(new AppleNotificationServerBasicImpl(keystore, password, production), payload, threads);
- }
-
-
- /**
- * Create group of devices ready to be dispatched to worker threads.
- *
- * @param devices a large list of devices
- * @param threads the number of threads to group devices for
- * @return
- */
- private static List> groupDevices(List devices, int threads) {
- List> groups = new Vector>(threads);
- int total = devices.size();
- int devicesPerThread = (total / threads);
- if (total % threads > 0) devicesPerThread++;
- //System.out.println("Making "+threads+" groups of "+devicesPerThread+" devices out of "+total+" devices in total");
- for (int i = 0; i < threads; i++) {
- int firstDevice = i * devicesPerThread;
- if (firstDevice >= total) break;
- int lastDevice = firstDevice + devicesPerThread - 1;
- if (lastDevice >= total) lastDevice = total - 1;
- lastDevice++;
- //System.out.println("Grouping together "+(lastDevice-firstDevice)+" devices (#"+firstDevice+" to "+lastDevice+")");
- List threadDevices = devices.subList(firstDevice, lastDevice);
- groups.add(threadDevices);
- }
- return groups;
- }
-
-
- /**
- * Start all notification threads.
- *
- * This method returns immediately, as all threads start working on their own.
- * To wait until all threads are finished, use the waitForAllThreads() method.
- */
- public final synchronized NotificationThreads start() {
- if (threadsRunning > 0) throw new IllegalStateException("NotificationThreads already started (" + threadsRunning + " still running)");
- assignThreadsNumbers();
- for (NotificationThread thread : threads) {
- threadsRunning++;
- thread.start();
- }
- if (listener != null) listener.eventAllThreadsStarted(this);
- return this;
- }
-
-
- /**
- * Configure in all threads the maximum number of notifications per connection.
- *
- * As soon as a thread reaches that maximum, it will automatically close the connection,
- * initialize a new connection and continue pushing more notifications.
- *
- * @param notifications the maximum number of notifications that threads will push in a single connection (default is 200)
- */
- public void setMaxNotificationsPerConnection(int notifications) {
- for (NotificationThread thread : threads)
- thread.setMaxNotificationsPerConnection(notifications);
- }
-
-
- /**
- * Configure in all threads the number of milliseconds that threads should wait between each notification.
- *
- * This feature is intended to alleviate intense resource usage that can occur when
- * sending large quantities of notifications very quickly.
-
- * @param milliseconds the number of milliseconds threads should sleep between individual notifications (default is 0)
- */
- public void setSleepBetweenNotifications(long milliseconds) {
- for (NotificationThread thread : threads)
- thread.setSleepBetweenNotifications(milliseconds);
- }
-
-
- /**
- * Get a list of threads created to push notifications.
- *
- * @return a list of threads
- */
- public List getThreads() {
- return threads;
- }
-
-
- /**
- * Get the progress listener, if any is attached.
- * @return a progress listener
- */
- public NotificationProgressListener getListener() {
- return listener;
- }
-
-
- /**
- * Attach an event listener to this object as well as all linked threads.
- *
- * @param listener
- */
- public void setListener(NotificationProgressListener listener) {
- this.listener = listener;
- for (NotificationThread thread : threads)
- thread.setListener(listener);
- }
-
-
- /**
- * Worker threads invoke this method as soon as they have completed their work.
- * This method tracks the number of threads still running, allowing us
- * to detect when ALL threads have finished.
- *
- * When all threads are done working, this method fires an AllThreadsFinished
- * event to the attached listener (if one is present) and wakes up any
- * object that is waiting for the waitForAllThreads() method to return.
- *
- * @param notificationThread
- */
- protected void threadFinished(NotificationThread notificationThread) {
- threadsRunning--;
- if (threadsRunning == 0) {
- if (listener != null) listener.eventAllThreadsFinished(this);
- try {
- synchronized (finishPoint) {
- finishPoint.notifyAll();
- }
- } catch (Exception e) {
- }
- }
- }
-
-
- /**
- * Wait for all threads to complete their work.
- *
- * This method blocks and returns only when all threads are done.
- *
- * @throws InterruptedException
- */
- public void waitForAllThreads() throws InterruptedException {
- try {
- synchronized (finishPoint) {
- finishPoint.wait();
- }
- } catch (IllegalMonitorStateException e) {
- /* All threads are most likely already done, so we ignore this */
- }
- }
-
-
- /**
- * Assign unique numbers to worker threads.
- * Thread numbers allow each thread to generate message identifiers that
- * are unique to all threads in the group.
- */
- private void assignThreadsNumbers() {
- int t = 1;
- for (NotificationThread thread : threads)
- thread.setThreadNumber(t++);
- }
-
-
- /**
- * Get a list of all notifications pushed by all threads.
- *
- * @return a list of pushed notifications
- */
- public List getPushedNotifications() {
- int capacity = 0;
- for (NotificationThread thread : threads)
- capacity += thread.getPushedNotifications().size();
- List all = new Vector(capacity);
- for (NotificationThread thread : threads)
- all.addAll(thread.getPushedNotifications());
- return all;
- }
-
-
- /**
- * Get a list of all notifications that all threads attempted to push but that failed.
- *
- * @return a list of failed notifications
- */
- public List getFailedNotifications() {
- return PushedNotification.findFailedNotifications(getPushedNotifications());
- }
-
-
- /**
- * Get a list of all notifications that all threads attempted to push and succeeded.
- *
- * @return a list of successful notifications
- */
- public List getSuccessfulNotifications() {
- return PushedNotification.findSuccessfulNotifications(getPushedNotifications());
- }
-
-}
diff --git a/pom.xml b/pom.xml
index 7b9143275..7a9973d0b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -93,7 +93,6 @@
gxmaps
gxoffice
gxsearch
- javapns
android
gxgeospatial
gxodata