/*
* TODO: The instancesByTrackingNumber will increase unbounded unless fixed
* Created on Apr 27, 2004
*
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
package net.reliableresponse.notification.providers;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Vector;
import net.reliableresponse.notification.Notification;
import net.reliableresponse.notification.NotificationException;
import net.reliableresponse.notification.broker.BrokerFactory;
import net.reliableresponse.notification.device.Device;
import net.reliableresponse.notification.device.PagerDevice;
import net.reliableresponse.notification.device.TAPDevice;
import net.reliableresponse.notification.usermgmt.User;
import net.reliableresponse.notification.util.StringUtils;
import net.reliableresponse.notification.wctp.ClientResponse;
import net.reliableresponse.notification.wctp.WctpException;
import net.reliableresponse.notification.wctp.WctpLibrary;
import org.w3c.dom.DOMException;
/**
* @author drig
*
* To change the template for this generated type comment go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
public class WctpNotificationProvider extends AbstractNotificationProvider {
String url, parameter, contentType;
String trackingNumber;
String sender;
String username, password;
WctpLibrary library;
long lastUpdated;
long pollTime;
int status = Notification.PENDING;
private static Hashtable libraries;
private static Hashtable responses;
public WctpNotificationProvider(String url, String parameter, String contentType) {
init (url, parameter, contentType, null, null);
}
public WctpNotificationProvider(String url, String parameter, String contentType, String username, String password) {
init (url, parameter, contentType, username, password);
}
public WctpNotificationProvider() {
}
public void init (Hashtable params) {
String url = (String)params.get("url");
String parameter = (String)params.get("parameter");
String contentType = (String)params.get("contentType");
String trackingNumber = (String)params.get("tracking number");
String username = (String)params.get("username");
String password = (String)params.get("password");
setTrackingNumber(trackingNumber);
init (url, parameter, contentType, username, password);
}
public void init (String url, String parameter, String contentType, String username, String password) {
this.sender = BrokerFactory.getConfigurationBroker().getStringValue("wctp.replyto");
if ((sender == null) || (sender.length() <= 0)) {
sender = "Reliable Response Notification";
}
this.url = url;
this.parameter = parameter;
this.contentType = contentType;
this.username = username;
this.password = password;
if (libraries == null) {
libraries = new Hashtable();
}
library = (WctpLibrary)libraries.get (url);
library = new WctpLibrary(url, parameter, contentType, username, password);
if (library == null) {
library = new WctpLibrary(url, parameter, contentType, username, password);
libraries.put (url, library);
}
if (responses == null) {
responses = new Hashtable();
}
lastUpdated = 0;
pollTime = 60000;
}
public Hashtable getParameters (Notification notification, Device device) {
Hashtable params = new Hashtable();
if (url == null) url = "";
params.put ("url", url);
if (parameter == null) parameter = "";
params.put ("parameter", parameter);
if (contentType == null) contentType= "";
params.put ("contentType", contentType);
params.put ("tracking number", "000000");
if (username != null) {
params.put ("username", username);
}
if (password != null) {
params.put ("password", password);
}
return params;
}
public Hashtable sendNotification(Notification notification, Device device) throws NotificationException {
User user = (User)notification.getRecipient();
String summary = notification.getSubject();
String[] optionsArray = notification.getSender().getAvailableResponses(notification);
Vector options = new Vector();
for (int i = 0; i < optionsArray.length; i++) {
options.addElement(optionsArray[i]);
}
String message = notification.getDisplayText();
if (StringUtils.isEmpty(message)) {
message = notification.getSubject();
}
String response = null;
try {
response = library.sendMessage(((PagerDevice) device)
.getNormalizedNumber(), sender, message, options);
} catch (IOException e) {
if (((PagerDevice)device).doFailoverToModem()) {
TAPDevice tapDevice = new TAPDevice();
tapDevice.initialize(getParameters(notification, device));
tapDevice.getNotificationProvider().sendNotification(notification, tapDevice);
} else {
throw new NotificationException(NotificationException.TEMPORARILY_FAILED, e.getMessage());
}
}
try {
ClientResponse cr = library.readClientResponse(response);
if (((int)cr.getCode()/100) == 4) {
throw new NotificationException(cr.getCode(), cr.getStatus());
}
if (((int)cr.getCode()/100) == 3) {
throw new NotificationException(cr.getCode(), cr.getStatus());
}
Hashtable params = new Hashtable();
setTrackingNumber(cr.getTrackingNumber());
params.put ("url", url);
if (parameter != null)
params.put ("parameter", parameter);
params.put ("contentType", contentType);
params.put ("tracking number", getTrackingNumber());
if (username != null) {
params.put ("username", username);
}
if (password != null) {
params.put ("password", password);
}
return params;
} catch (WctpException e1) {
//BrokerFactory.getLoggingBroker().logError(e1);
throw new NotificationException(400, e1.getMessage());
}
}
private synchronized ClientResponse getClientResponse(Notification page) {
ClientResponse clientResponse = null;
if (System.currentTimeMillis() > (lastUpdated + pollTime)) {
try {
Device[] devices = ((User) page.getRecipient())
.getDevices();
String recipientPager = "";
if (devices.length > 0) {
int i = 0;
while ((i < devices.length) && (!(devices[i] instanceof PagerDevice))) i++;
if (i<devices.length) {
recipientPager = ((PagerDevice)devices[i]).getNormalizedNumber();
}
}
String clientQuery = library.formatWCTPClientQuery(recipientPager,
sender, getTrackingNumber());
BrokerFactory.getLoggingBroker().logDebug("query = "+clientQuery);
String response = library.sendMessage(clientQuery);
BrokerFactory.getLoggingBroker().logDebug("response = " + response);
clientResponse = library.readClientQueryResponse(response);
if ((clientResponse.getCode()/100) == 4) {
page.addMessage("Querying notification status failed because: "+clientResponse.getStatus()+". Two-way communication may not work", null);
}
lastUpdated = System.currentTimeMillis();
} catch (DOMException e) {
BrokerFactory.getLoggingBroker().logError(e);
} catch (IOException e) {
BrokerFactory.getLoggingBroker().logError(e);
} catch (WctpException e) {
BrokerFactory.getLoggingBroker().logError(e);
}
} else {
BrokerFactory.getLoggingBroker().logDebug("Waiting " +((lastUpdated + pollTime) - System.currentTimeMillis())+" millis before checking wctp again");
}
return clientResponse;
}
/**
*
* @param pageId
* The ID of the notification previously sent
* @return A english-readable status. null if the message is unknown
*/
public int getStatus(Notification notification) {
// Check to see if the send failed
if (trackingNumber == null) trackingNumber = "000000";
if (trackingNumber.equals("000000")) {
return Notification.NORMAL;
}
ClientResponse response = getClientResponse(notification);
BrokerFactory.getLoggingBroker().logDebug("Wctp Message #"+trackingNumber+" response = "+response);
if (response == null) return status;
status = getStatusFromResponse(response);
return status;
}
private int getStatusFromResponse(ClientResponse response) {
String[] messages = response.getMessages();
for (int i = 0; i < messages.length; i++) {
if (messages[i].toLowerCase().equals ("confirm")) {
status= Notification.CONFIRMED;
return status;
}
if (messages[i].toLowerCase().equals ("pass")) {
status= Notification.CONFIRMED;
return status;
}
}
String statusString = response.getStatus();
BrokerFactory.getLoggingBroker().logDebug("Wctp Message #"+trackingNumber+" returned "+statusString);
if (statusString != null) {
if (statusString.toLowerCase().equals ("confirmed")) {
status = Notification.CONFIRMED;
return status;
} else if (statusString.equalsIgnoreCase("queued")) {
status = Notification.PENDING;
return status;
} else if (statusString.equalsIgnoreCase("delivered")) {
status = Notification.DELIVERED;
return status;
} else if (statusString.toLowerCase().indexOf("failed")>=0) {
status = Notification.FAILED;
return status;
}
}
return status;
}
public String[] getResponses(Notification notification) {
BrokerFactory.getLoggingBroker().logDebug("WCTP Getting responses");
Vector clientResponses = new Vector();
ClientResponse clientResponse = getClientResponse(notification);
if (clientResponse != null) {
status = getStatusFromResponse(clientResponse);
Vector knownResponses = (Vector) responses.get(notification);
if (knownResponses == null) knownResponses = new Vector();
String[] messages = clientResponse.getMessages();
BrokerFactory.getLoggingBroker().logDebug("We have "+knownResponses.size()+" known responses and "+messages.length+" messages");
for (int i = knownResponses.size(); i < messages.length; i++) {
BrokerFactory.getLoggingBroker().logDebug("message["+i+"]="+messages[i]);
clientResponses.addElement(messages[i]);
knownResponses.addElement(messages[i]);
}
responses.put (notification, knownResponses);
}
return (String[]) clientResponses.toArray(new String[0]);
}
public boolean isConfirmed(Notification page) {
String[] responses = getResponses(page);
for (int i = 0; i < responses.length; i++) {
if (responses[i].toLowerCase().equals ("confirm")) {
return true;
}
}
return false;
}
public boolean isPassed(Notification page) {
String[] responses = getResponses(page);
for (int i = 0; i < responses.length; i++) {
if (responses[i].toLowerCase().equals ("pass")) {
return true;
}
}
return false;
}
/**
*
* @param pageId
* @return Whether the cancellation was successfull
*/
public boolean cancelPage(Notification page) {
//TODO: First fill in the required functions to the WctpLibary
return false;
}
public String getTrackingNumber() {
return trackingNumber;
}
public void setTrackingNumber(String trackingNumber) {
this.trackingNumber = trackingNumber;
}
public String getName() {
return "Online Pager Provider";
}
public String toString() {
return "Two-Way Pager";
}
public WctpLibrary getWctpLibrary() {
return library;
}
}