Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

eml #7

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<groupId>com.notnoop.mpns</groupId>
<artifactId>mpns</artifactId>
<name>Java Microsoft Push Notification Service Library</name>
<version>0.0.1-SNAPSHOT</version>
<version>0.0.2</version>

<!-- Inherit the Sonatype OSS deployment configuration -->
<!--
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/notnoop/mpns/MpnsNotification.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,5 @@ public interface MpnsNotification {
* @return the notification identifier
*/
public List<? extends Entry<String, String>> getHttpHeaders();

}
24 changes: 24 additions & 0 deletions src/main/java/com/notnoop/mpns/MpnsNotificationBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
*/
package com.notnoop.mpns;

import com.notnoop.mpns.notifications.CycleTileNotification;
import com.notnoop.mpns.notifications.FlipTileNotification;
import com.notnoop.mpns.notifications.IconicTileNotification;
import com.notnoop.mpns.notifications.RawNotification;
import com.notnoop.mpns.notifications.TileNotification;
import com.notnoop.mpns.notifications.ToastNotification;
Expand All @@ -52,6 +55,27 @@ public MpnsNotificationBuilder() {}
public TileNotification.Builder tile() {
return new TileNotification.Builder();
}

/**
* Windows 8: Flip Tile
*/
public FlipTileNotification.Builder flipTile() {
return new FlipTileNotification.Builder();
}

/**
* Windows 8: Iconic Tile
*/
public IconicTileNotification.Builder iconicTile() {
return new IconicTileNotification.Builder();
}

/**
* Windows 8: Cycle Tile
*/
public CycleTileNotification.Builder cycleTile() {
return new CycleTileNotification.Builder();
}

/**
* Sets the notification type to a Toast notification
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/notnoop/mpns/MpnsService.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ void push(String subscriptionUri, String payload,
*/
void push(String subscriptionUri, MpnsNotification message)
throws NetworkIOException;

/**
* Starts the service.
*
Expand Down
86 changes: 86 additions & 0 deletions src/main/java/com/notnoop/mpns/MpnsServiceBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,27 @@
*/
package com.notnoop.mpns;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.Arrays;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;

import org.apache.http.HttpHost;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
Expand Down Expand Up @@ -67,6 +82,42 @@ public class MpnsServiceBuilder {
private int timeout = -1;

private MpnsDelegate delegate;

// Authenticated calls
private SecurityInfo securityInfo;

public static class SecurityInfo {
private byte[] cert;
private String password;
private String name;
private String provider;

public SecurityInfo(byte[] cert, String password, String securityName, String securityProvider) {
if( cert == null || cert.length == 0 ||
password == null || "".equals(password.trim()) ||
securityName == null || "".equals(securityName.trim()) ) {
// provider is optional
throw new IllegalArgumentException("Please provide certificate, password, and name");
}
this.cert = Arrays.copyOf(cert, cert.length);
this.password = password;
this.name = securityName;
this.provider = securityProvider;
}

public byte[] getCert() {
return cert;
}
public String getPassword() {
return password;
}
public String getName() {
return name;
}
public String getProvider() {
return provider;
}
}

/**
* Constructs a new instance of {@code MpnsServiceBuilder}
Expand Down Expand Up @@ -151,6 +202,14 @@ public MpnsServiceBuilder asQueued() {
this.isQueued = true;
return this;
}

/**
* Authenticated
*/
public MpnsServiceBuilder asAuthenticated(SecurityInfo securityInfo) {
this.securityInfo = securityInfo;
return this;
}

/**
* Sets the timeout for the connection
Expand Down Expand Up @@ -190,6 +249,33 @@ public MpnsService build() {
if (proxy != null) {
client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
}

if( securityInfo != null ) {
try {
KeyStore keyStore = null;
if( securityInfo.getProvider() == null ) {
keyStore = KeyStore.getInstance(securityInfo.getName());
} else {
keyStore = KeyStore.getInstance(securityInfo.getName(), securityInfo.getProvider());
}
keyStore.load(new ByteArrayInputStream(securityInfo.getCert()),
securityInfo.getPassword().toCharArray());

KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmfactory.init(keyStore, securityInfo.getPassword().toCharArray());
KeyManager[] km = kmfactory.getKeyManagers();

// create SSL socket factory
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(km, null, null);
org.apache.http.conn.ssl.SSLSocketFactory sslSocketFactory = new org.apache.http.conn.ssl.SSLSocketFactory(sslContext);

Scheme https = new Scheme("https", 443, sslSocketFactory);
client.getConnectionManager().getSchemeRegistry().register(https);
} catch( Exception e ) {
throw new IllegalArgumentException(e);
}
}

if (timeout > 0) {
HttpParams params = client.getParams();
Expand Down
45 changes: 39 additions & 6 deletions src/main/java/com/notnoop/mpns/internal/Utilities.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,17 @@
*/
package com.notnoop.mpns.internal;

import java.io.UnsupportedEncodingException;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;

import com.notnoop.mpns.DeliveryClass;
import com.notnoop.mpns.MpnsDelegate;
import com.notnoop.mpns.MpnsNotification;
import com.notnoop.mpns.MpnsResponse;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;

public final class Utilities {
private Utilities() { throw new AssertionError("Uninstantiable class"); }

Expand All @@ -66,6 +64,29 @@ public static ThreadSafeClientConnManager poolManager(int maxConnections) {
public static String ifNonNull(Object cond, String value) {
return cond != null ? value : "";
}

public static String xmlElement(String name, String content) {
return xmlElement(name, content, false);
}

public static String xmlElementClear(String name, String content) {
return xmlElement(name, content, true);
}

private static String xmlElement(String name, String content, boolean isClear) {
if( content == null || "".equals(content.trim())) {
return "";
}
StringBuilder sb = new StringBuilder(500);
sb.append("<wp:").append(name);
if( isClear ) {
sb.append(" Action=\"Clear\"");
}
sb.append(">");
sb.append(escapeXml(content));
sb.append("</wp:").append(name).append(">");
return sb.toString();
}

public static String escapeXml(String value) {
if (value == null) {
Expand Down Expand Up @@ -115,7 +136,7 @@ public static MpnsResponse logicalResponseFor(HttpResponse response) {
}

if (r.getDeviceConnectionStatus() != null
&& !r.getNotificationStatus().equals(headerValue(response, "X-DeviceConnectionStatus"))) {
&& !r.getDeviceConnectionStatus().equals(headerValue(response, "X-DeviceConnectionStatus"))) {
continue;
}

Expand Down Expand Up @@ -143,4 +164,16 @@ public static void fireDelegate(MpnsNotification message, HttpResponse response,
}
}
}

public static int getTileDelivery(DeliveryClass delivery) {
if( delivery == null ) {
delivery = DeliveryClass.IMMEDIATELY;
}
switch (delivery) {
case IMMEDIATELY: return 1;
case WITHIN_450: return 11;
case WITHIN_900: return 21;
default: return 1; // IMMEDIATELY is the default
}
}
}
Loading