/*
* HTTPPushDemo.java
*
* Created on July 13, 2001, 10:45 AM
* Copyright � 1998-2011 Research In Motion Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Note: For the sake of simplicity, this sample application may not leverage
* resource bundles and resource strings. However, it is STRONGLY recommended
* that application developers make use of the localization features available
* within the BlackBerry development platform to ensure a seamless application
* experience across a variety of languages and geographies. For more information
* on localizing your application, please refer to the BlackBerry Java Development
* Environment Development Guide associated with this release.
*/
package com.rim.samples.server.httppushdemo;
import java.io.*;
import javax.swing.*;
import javax.swing.border.*;
import java.net.*;
import java.util.*;
import java.awt.Color;
/**
* <p>The HTTPPushDemo class provides a simple PUSH server sample.
* <p>This program will send text to a listening device. The associated client demo
* is HTTPPushDemo in the com.rim.samples.device package. Start up both the device simulator
* and MDS before executing this program. For reliable push, append the port that you are pushing
* to in rimpublic.property file (push.application.reliable.ports):
* <code>push.application.reliable.ports=7874,<b>100</b></code
*
* <p> The general form of the URL for posting (pushing) data to the device is:
* http://<host>:<port>/push?DESTINATION=<device pin>&PORT=<device_port>&REQUESTURI=<post uri>
*/
public class HTTPPushDemo extends javax.swing.JFrame {
//constants -----------------------------------------------------------------
private static final String RESOURCE_PATH = "com/rim/samples/server/httppushdemo/resources";
private static final String DEVICE_PIN = "2100000A";
private static final String DEVICE_PORT = "100";
private static final int MDS_PORT = 8080;
private String requestTemplate;
private String notifyURL="http://localhost:7778";
private Random random= new Random();
private Thread notificationThread;
//statics -------------------------------------------------------------------
private static ResourceBundle _resources = java.util.ResourceBundle.getBundle(RESOURCE_PATH);
//constructors --------------------------------------------------------------
/** Creates a new HTTPPushDemo instance*/
public HTTPPushDemo() {
initComponents ();
pack ();
//sizing code for the main frame
setSize(_panel.getWidth(), _panel.getHeight());
setLocation(100,100);
notificationThread= new NotificationThread();
}
private URL getPushURL(String DevicePin)
{
/**
* The format of the URL is:
* http://<host>:<port>/push?DESTINATION=<device pin>&PORT=<device_port>&REQUESTURI=<post uri>
*/
URL _pushURL = null;
try {
if ((DevicePin == null) || (DevicePin.length() == 0))
{
DevicePin = DEVICE_PIN;
}
_pushURL = new URL("http", "localhost", MDS_PORT, "/push?DESTINATION="+ DevicePin +"&PORT="+DEVICE_PORT+"&REQUESTURI=localhost");
} catch (MalformedURLException e) {
System.err.println(e.toString());
}
return _pushURL;
}
/**
* This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the FormEditor.
*/
private void initComponents() {//GEN-BEGIN:initComponents
_panel = new javax.swing.JPanel();
_textArea= new javax.swing.JTextArea();
_pinField = new javax.swing.JTextField(DEVICE_PIN);
_label = new javax.swing.JTextArea();
_notification=new javax.swing.JTextArea();
_rimButton= new javax.swing.JRadioButton("rim", true);
_papButton= new javax.swing.JRadioButton("pap");
_buttonGroup= new javax.swing.ButtonGroup();
_buttonGroup.add(_rimButton);
_buttonGroup.add(_papButton);
_sendButton = new javax.swing.JButton();
getContentPane().setLayout(null);
setTitle(_resources.getString("HTTPPushDemo.title"));
setResizable(false);
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
exitForm(evt);
}
});
_panel.setLayout(null);
_panel.setPreferredSize(getSize());
_textArea.setToolTipText(_resources.getString("HTTPPushDemo._textField.toolTipText"));
_panel.add(_textArea);
_textArea.setBounds(10, 50, 270, 100);
_textArea.setBorder(new LineBorder(Color.BLACK));
_pinField.setToolTipText(_resources.getString("HTTPPushDemo._pinField.toolTipText"));
_panel.add(_pinField);
_pinField.setBounds(10, 170, 150, 30);
_panel.add(_rimButton);
_panel.add(_papButton);
_rimButton.setBounds(170, 170, 50, 30);
_papButton.setBounds(240, 170, 50, 30);
_label.setWrapStyleWord(true);
_label.setLineWrap(true);
_label.setEditable(false);
_label.setText(_resources.getString("HTTPPushDemo._label.text"));
_label.setBackground((java.awt.Color) javax.swing.UIManager.getDefaults ().get ("Button.background"));
_panel.add(_label);
_label.setBounds(10, 10, 270, 40);
_sendButton.setText(_resources.getString("HTTPPushDemo._sendButton.label"));
_sendButton.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
sendButtonMouseClicked(evt);
}
});
_panel.add(_sendButton);
_sendButton.setLocation(10, 210);
_sendButton.setSize(_sendButton.getPreferredSize());
JScrollPane _scrollPane = new javax.swing.JScrollPane(_notification);
_scrollPane.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
_panel.add(_scrollPane);
_scrollPane.setBounds(10,250,270, 150);
getContentPane().add(_panel);
_panel.setBounds(0, 0, 300, 450);
}//GEN-END:initComponents
private void sendButtonMouseClicked(java.awt.event.MouseEvent evt)
{//GEN-FIRST:event_sendButtonMouseClicked
String text =_textArea.getText();
if(_rimButton.isSelected()) postData(text);
else if(_papButton.isSelected()) papPush(text);
}//GEN-LAST:event_sendButtonMouseClicked
/**
* <p>posts the specified data to the device
* <p>The URL is hardcoded for the purposes of this demo, and takes the form:
* http://<host>:<port>/push?DESTINATION=<device pin>&PORT=<device_port>&REQUESTURI=<post uri>
* param data the data to post
*
*/
private void postData(String data)
{
String pushId="pushID:"+random.nextInt();
setupNotifyThread();
try {
URL url = getPushURL(_pinField.getText());
System.out.println(_resources.getString("HTTPPushDemo.status.sendingToString") + url.toString());
//open the connection using the static member...
HttpURLConnection conn =(HttpURLConnection)url.openConnection();
conn.setDoInput(true);//For receiving the confirmation
conn.setDoOutput(true);//For sending the data
conn.setRequestMethod("POST");//Post the data to the proxy
conn.setRequestProperty("X-RIM-PUSH-ID", pushId);
conn.setRequestProperty("X-RIM-Push-NotifyURL", notifyURL);
// To enable application level push reliability, uncomment the following line
//conn.setRequestProperty("X-RIM-Push-Reliability-Mode","APPLICATION");
//Write the data
OutputStream out = conn.getOutputStream();
out.write(data.getBytes());
out.close();
InputStream ins =conn.getInputStream();
int contentLength =conn.getContentLength();
System.out.println( _resources.getString("HTTPPushDemo.status.contentLengthDescription")+ contentLength);
if (contentLength > 0)
{
byte[] someArray = new byte [contentLength];
DataInputStream dins = new DataInputStream(ins);
dins.readFully(someArray);
System.out.println(new String(someArray));
}
conn.disconnect();
} catch (IOException e) {
System.err.println(e);
}
}
private void readPapTemplate()
{
try {
String papFilename = "com/rim/samples/server/httppushdemo/pap_push.txt";
InputStream ins = new BufferedInputStream(new FileInputStream(papFilename));
ByteArrayOutputStream bouts = new ByteArrayOutputStream();
copyStreams(ins, bouts);
this.requestTemplate = new String(bouts.toByteArray());
} catch (Exception exception) {
exception.printStackTrace();
}
}
private void setupNotifyThread()
{
if( !notificationThread.isAlive() )
{
notificationThread = new NotificationThread();
notificationThread.start();
}
}
private void papPush(String data)
{
String pushId="pushID:"+random.nextInt();
setupNotifyThread();
readPapTemplate();
try {
String mdsHost = "localhost";
URL mdsUrl = new URL("http", mdsHost, MDS_PORT, "/pap");
System.out.println(" sending PAP request to " + mdsUrl.toString() + "; pushId = " + pushId);
HttpURLConnection mdsConn = (HttpURLConnection)mdsUrl.openConnection();
String boundary = "";
boundary = "asdlfkjiurwghasf";
mdsConn.setRequestProperty("Content-Type", "multipart/related; type=\"application/xml\"; boundary=" + boundary);
mdsConn.setRequestProperty("X-Wap-Application-Id", "/");
mdsConn.setRequestProperty("X-Rim-Push-Dest-Port","100");
mdsConn.setRequestMethod("POST");
mdsConn.setAllowUserInteraction(false);
mdsConn.setDoInput(true);
mdsConn.setDoOutput(true);
String output = requestTemplate.replaceAll("\\$\\(pushid\\)", pushId);
output = output.replaceAll("\\$\\(boundary\\)", boundary);
output = output.replaceAll("\\$\\(notifyURL\\)", "" + notifyURL);
output = output.replaceAll("\\$\\(pin\\)", "" + _pinField.getText());
String deliveryMethod = "application-level";
output = output.replaceAll("\\$\\(deliveryMethod\\)", deliveryMethod);
output = output.replaceAll("\\$\\(headers\\)", "Content-Type: text/plain");
output = output.replaceAll("\\$\\(content\\)", data);
output = output.replaceAll("\r\n", "EOL");
output = output.replaceAll("\n", "EOL");
output = output.replaceAll("EOL", "\r\n");
System.out.println(output);
OutputStream outs = mdsConn.getOutputStream();
copyStreams(new ByteArrayInputStream(output.getBytes()), outs);
mdsConn.connect();
ByteArrayOutputStream response = new ByteArrayOutputStream();
copyStreams(mdsConn.getInputStream(), response);
int httpCode = mdsConn.getResponseCode();
if (httpCode != HttpURLConnection.HTTP_ACCEPTED) {
throw new Exception("MDS returned HTTP status: " + httpCode);
}
} catch (Exception exception) {
System.out.println(" encountered error on submission: " + exception.toString());
}
}
public void copyStreams(InputStream ins, OutputStream outs) throws IOException
{
byte [] buffer = new byte[1024];
int bytesRead;
for(;;)
{
bytesRead = ins.read(buffer);
System.out.println(buffer);
if (bytesRead <= 0) break;
outs.write(buffer, 0, bytesRead);
}
}
/** Exit the Application */
private void exitForm(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_exitForm
System.exit (0);
}//GEN-LAST:event_exitForm
/**
* @param args the command line arguments
*/
public static void main (String args[]) {
new HTTPPushDemo().setVisible(true);
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JPanel _panel;
private javax.swing.JTextArea _textArea;
private javax.swing.JTextField _pinField;
private javax.swing.JTextArea _label;
private javax.swing.JTextArea _notification;
private javax.swing.JButton _sendButton;
private javax.swing.JRadioButton _rimButton;
private javax.swing.JRadioButton _papButton;
private javax.swing.ButtonGroup _buttonGroup;
// End of variables declaration//GEN-END:variables
public class NotificationThread extends Thread {
public void run()
{
try {
System.out.println("Waiting for notification on port " + 7778 + "...");
while (true)
{
ServerSocket serverSocket = new ServerSocket(7778);
serverSocket.setSoTimeout(120000);
try {
Socket clientSocket = serverSocket.accept();
_notification.setText("Received notification:");
InputStream input = clientSocket.getInputStream();
StringBuffer str= new StringBuffer();
int byteRead = input.read();
while ((byteRead != -1) && (input.available() > 0))
{
str.append((char)byteRead);
byteRead = input.read();
}
_notification.append(str.toString());
PrintWriter output = new PrintWriter(clientSocket.getOutputStream());
output.close();
clientSocket.close();
} catch (SocketTimeoutException ste) {
System.out.println("Notification connection timeout. Restarting...");
}
serverSocket.close();
}
} catch (Exception exception) {
exception.printStackTrace();
}
}
}
}