/* * 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(); } } } }