Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: mobile/bearer/http/TalkingWithProxy.java


1   /**
2    * Following fields form http header are used:
3    * content-length - length of message.
4    * jms4j2me-code - an integer representing what is the message kind
5    * jms4j2me-owner - owner client application identifier
6    * jms4j2me-id - id message identifier
7    * jms4j2me-action - if set to "acknowledgesPlease" denotes that
8    * each field mentioned above is obligatory.
9    */
10  
11  
12  package mobile.bearer.http;
13  
14  import java.io.IOException;
15  import java.io.InputStream;
16  import java.io.OutputStream;
17  import java.lang.String;
18  import javax.microedition.io.*;
19  import mobile.protocol.Reply;
20  import java.util.Date;
21  /**
22   * <p>
23   * The lowest level of communication,
24   * Makes connection with proxy using HTTP protocol.
25   * </p>
26   */
27  public class TalkingWithProxy  {
28    public static final String MOBILEFIELD = "jms4j2me-mobile";
29    public static final String OWNERFIELD  = "jms4j2me-owner";
30    public static final String CODEFIELD   = "jms4j2me-code";
31    public static final String IDFIELD     = "jms4j2me-id";
32    public static final String LENGTHFIELD = "jms4j2me-message-length";
33    public static final String ACTIONFIELD = "jms4j2me-action";
34  
35    ///////////////////////////////////////
36    // attributes
37  
38  
39    /**
40     * <p>
41     * How many messages where sent since last succesful acknowledge.
42     * </p>
43     */
44    private int messagesSent;
45  
46    /**
47     * <p>
48     * How many messages should be sent before asking if they arrived.
49     * </p>
50     */
51    private int messagesPerPack;
52  
53    /**
54     * <p>
55     * My proxy's URL.
56     * </p>
57     */
58    private String proxyUrl;
59  
60  
61    /**
62     * <p>
63     * Connection representation.
64     * </p>
65     */
66    /*    private public Connector myHttpConnection = 0;
67     */
68  //  private HttpConnection myHttpConnection;
69  
70  
71    /**
72     * <p>
73     * Informations from proxy should appear on this stream.
74     * </p>
75     */
76    private InputStream myInputStream;
77  
78    /**
79     * <p>
80     * Stream for sending informations to proxy.
81     * </p>
82     */
83  //  private OutputStream myOutputStream;
84  
85    /**
86     * <p>
87     * Mobile unique identifier. Imei if found, else random number.
88     * </p>
89     */
90    private String mobile;
91  
92    ///////////////////////////////////////
93    // operations
94  
95  
96  
97  
98      /**
99       * adds the message to the console output logs - for debugging
100      * @param msg message with debugging information for printing
101      */
102     private void log(String msg){
103       System.out.println("TWP " + msg);
104       }
105 
106   /**
107    * <p>
108    * Constructor.
109    * </p><p>
110    *
111    * </p><p>
112    * @param proxyUrl URL of my proxy
113    * @param msgPerPack amount of messages sent before asking for acknowledge.
114    * </p>
115    */
116   public TalkingWithProxy(String proxyUrl, int msgPerPack) {
117     this.proxyUrl = proxyUrl;
118     this.messagesPerPack = messagesPerPack;
119     messagesSent = 0;
120 //    myInputStream = null;
121 //    myOutputStream = null;
122 //    myHttpConnection = null;
123 
124     if ((mobile = System.getProperty("profiles.imei")) == null){
125      //oho, i'm involved from emulator
126      // TODO: do it better!
127      mobile = Long.toString(new Date().getTime());
128     };
129   } // end TalkingWithProxy
130 
131   /**
132    * <p>
133    * Opens connection with its proxy.
134    * </p><p>
135    *
136    */
137   public void openConnection() {
138 //    InputStream s;
139 //    try{
140 //      if (myHttpConnection == null)
141 //        myHttpConnection = (HttpConnection)Connector.open(proxyUrl);
142 //
143 //      myHttpConnection.setRequestProperty("User-Agent",
144 //                                          "Profile/MIDP-1.0 Configuration/CLDC-1.0");
145 //      myHttpConnection.setRequestProperty("Content-Language", "en-US");
146 //
147 //      if (myOutputStream == null)
148 //        myOutputStream = myHttpConnection.openOutputStream();
149 //      if (myInputStream == null)
150 //        myInputStream = myHttpConnection.openInputStream();
151 //    } catch(IOException myExc){
152       // DOIT!
153 //    }
154   } // end OpenConnection
155 
156   /**
157    * <p>
158    * Sends given message.
159    * </p><p>
160    *
161    * @param code an integer representing what is the message kind
162    * </p><p>
163    * @param owner client application identifier
164    * </p><p>
165    * @param id message identifier
166    * </p><p>
167    * @param msg serialized (using own mechanism) frame body
168    * </p><p>
169    * @throws NoConnectionException when proxy is unreacheable
170    * @throws NoDataException when no data can be fetched from proxy
171    *
172    * </p>
173    */
174   public void putNext(int code, int owner, int id, byte[] msg) throws NoConnectionException, NoDataException{
175 
176     log("sending: code =  " + code + ", owner = " + owner + ", id = " + id + ", msg = " + new String(msg));
177 
178     /* Connection should be used with care */
179     if (msg.length == 0)
180       throw new NoDataException();
181 
182     try {
183 //      openConnection();
184       HttpConnection c = null;
185 //      log("po httpconection c = null");
186       try{
187         log("otwieram połączenie z " + proxyUrl);
188         c = (HttpConnection) Connector.open(proxyUrl);
189       } catch (IllegalArgumentException e){
190         log("złapałem illegalArgumentException");
191       }
192       c.setRequestMethod(HttpConnection.POST);
193 
194       /* set fields in header */
195       c.setRequestProperty(MOBILEFIELD, mobile);
196       c.setRequestProperty(OWNERFIELD, new Integer(owner).toString());
197       c.setRequestProperty(CODEFIELD, new Integer(code).toString());
198       c.setRequestProperty(IDFIELD, new Integer(id).toString());
199       c.setRequestProperty(LENGTHFIELD, (new Integer(msg.length)).toString());
200       c.setRequestProperty("Content-Type", "application/octet-stream");
201       OutputStream os = c.openOutputStream();
202 //      System.out.println("putNext: \"" + new String(msg) + "\"");
203 
204       for (int i=0; i < msg.length; i++)
205         os.write(msg[i]);
206       os.flush();
207 //      log("wysłałem");
208       os.close();
209       c.close();
210     } catch (NullPointerException e){
211       log("catched NullPointerException - THATS A HUGE PROBLEM!");
212       e.printStackTrace();
213     } catch (IOException anIOExc){
214       log("putNext: throwing NoConnectionException becouse of IOException: " + anIOExc.toString());
215    //   anIOExc.printStackTrace();
216       throw new NoConnectionException();
217     }
218   } // end putNext
219 
220   /**
221    * <p>
222    * Ask proxy if there are any messages and receive one if so.
223    * </p><p>
224    *
225    *
226    * @param owner owner identifier
227    *
228    * @return a Reply - ownserialized message received from proxy.
229    * @throws NoConnectionException when proxy is unreachable
230    * @throws NoDataException wnen no data can be fetched from proxy
231    * </p>
232    */
233 public Reply getNext(int owner) throws NoConnectionException, NoDataException{
234 
235   /* what is received from the server */
236   StringBuffer b = new StringBuffer();
237 
238   /* my connection with the server */
239   HttpConnection c = null;
240 
241   /* values returned as a Reply */
242   int code, id;
243   byte data[];
244 
245   try {
246     long len = 0;
247     int ch = 0;
248     long count = 0;
249 
250     c = (HttpConnection) Connector.open(proxyUrl);
251     c.setRequestMethod(HttpConnection.GET);
252 
253     c.setRequestProperty(MOBILEFIELD, mobile);
254     c.setRequestProperty(OWNERFIELD, new Integer(owner).toString());
255 
256     /* read all header fields */
257     for (int a = 0; c.getHeaderFieldKey(a) != null; a++)
258       ;
259 
260     code = Integer.parseInt(c.getHeaderField(CODEFIELD));
261     id = Integer.parseInt(c.getHeaderField(IDFIELD));
262 
263     log("w getNext id = " + id);
264     InputStream is = c.openInputStream();
265     len = ( (HttpConnection) c).getLength();
266     /* content-length field is needed. */
267     if (len == 0) {
268       c.close();
269       is.close();
270       log("Server answers: no data.");
271       throw new NoDataException();
272     }
273 
274     data = new byte[ (int) len];
275 
276     int n = is.read(data, 0, data.length);
277     for (int i = 0; i < n; i++) {
278       ch = data[i] & 0x000000ff;
279       b.append( (char) ch);
280 //      System.out.println(ch);
281     }
282     System.out.println("getNext: \"" + b.toString() + "\"");
283     is.close();
284     c.close();
285   }
286   catch (IOException ex) {
287 //   log("złaapny ioexc. w getNext()");
288 //        ex.printStackTrace();
289     throw new NoConnectionException();
290   }
291   log("getNext zwraca reply");
292   int[] idArr = new int [1];
293   idArr[0] = id;
294 //  log("przed putAcknowledge w getNext");
295   putAcknowledge(idArr, owner);
296 // log("po putAcknowledge w getNext");
297   return new Reply(code, owner, id, data);
298 } // end getNext
299 
300   /**
301    * <p>
302    * Sends to proxy numbers of messages that was properly received.
303    * </p><p>
304    * </p><p>
305    * @param arr Array of messages numbers for acknowledge.
306    * @param owner owner identifier
307    * @throws NoDataException when given parameters consists no data
308    * @throws NoConnectionException when proxy is unreachable
309    * </p>
310    */
311     private void putAcknowledge(int[] arr, int owner) throws NoDataException, NoConnectionException {
312 //      log("doing putAcknowledge");
313       if (arr.length == 0)
314         throw new NoDataException();
315       if (arr.length != 1)
316         System.err.println("I can acknowledge one message at time only!");
317       try {
318         HttpConnection c = null;
319 
320         c = (HttpConnection) Connector.open(proxyUrl);
321         c.setRequestMethod(HttpConnection.HEAD);
322 
323         /* set fields in header */
324         c.setRequestProperty(MOBILEFIELD, mobile);
325         c.setRequestProperty(OWNERFIELD, new Integer(owner).toString());
326         log("putAcknowledge: id = " + arr[0]);
327         c.setRequestProperty(IDFIELD, new Integer(arr[0]).toString());
328         c.setRequestProperty("Content-Type", "application/octet-stream");
329         OutputStream os = c.openOutputStream();
330 
331         os.flush();
332         os.close();
333         c.close();
334       }
335       catch (IOException anIOExc) {
336 
337         log("putAcknowledge rzuca noConnectionExc");
338         anIOExc.printStackTrace();
339 //        throw new NoConnectionException();
340       }
341     } // end putAcknowledge
342 
343     /**
344      * <p>
345      * Ask server if there are any messages that I (mobile) had send and was properly delivered to proxy.
346      * </p><p>
347      *
348      * @param owner calling application id
349      *
350      * @return a int[] with numbers of message to acknowledge.
351      * @throws NoConnectionException when proxy is unreachable
352      * @throws NoDataException when proxy answers with no data
353      * </p>
354      */
355     public int[] getAcknowledge(int owner) throws NoConnectionException, NoDataException{
356 
357       /* my connection with the server */
358       HttpConnection c = null;
359       int[] result;
360 
361       try {
362         long len = 0;
363         int ch = 0;
364         long count = 0;
365 
366         c = (HttpConnection) Connector.open(proxyUrl);
367         c.setRequestMethod(HttpConnection.GET);
368 
369         c.setRequestProperty(MOBILEFIELD, mobile);
370         c.setRequestProperty(OWNERFIELD, new Integer(owner).toString());
371         c.setRequestProperty(ACTIONFIELD, "acknowledgesPlease");
372 
373         /* read all header fields */
374         for (int a = 0; c.getHeaderFieldKey(a) != null; a++)
375           ;
376 
377         InputStream is = c.openInputStream();
378         len = ( (HttpConnection) c).getLength();
379         /* content-length field is needed. */
380         if (len == 0) {
381           c.close();
382           is.close();
383           log("No content-length field");
384           throw new NoDataException();
385         }
386 
387         byte data[];
388         data = new byte[ (int) len];
389         result = new int[ (int)len/4];
390         int n = is.read(data, 0, data.length);
391         int current = 0; /* message id counter */
392         int z;           /* bytes counter */
393         int id;          /* current id  */
394         n/=4;
395         System.out.println("n =" + n);
396         for (int i = 0; i < n; i++) {
397           for (z = 0; z < 4; z++){
398             ch = data[4 * i + z] & 0x000000ff;
399             current = current << 8;
400             current += ch;
401 //            System.out.println("getAckn zwraca:::");
402 //            System.out.println(ch);
403           }
404           result[i]=current;
405         }
406         is.close();
407         c.close();
408         return result;
409       }
410       catch (IOException ex) {
411         log("złaapny ioexc. w getAcknowledge()");
412         ex.printStackTrace();
413         throw new NoConnectionException();
414       }
415     } // end getAcknowledge
416 
417 
418     /**
419      * <p>
420      * Check whether mobile has connection with server. This method gives information about potential state of connection. Answering true doesn't mean that something rather might than might not be sent/received. Answering false says that the chance is near zero.
421      * </p><p>
422      * @return a boolean that say if proxy is reachable at the moment.
423      * </p>
424      */
425     public boolean connectionExists() {
426       return true;
427 //      return myHttpConnection != null;
428     } // end connectionExists
429 
430     public void setUrl(String _url){
431         proxyUrl = _url;
432       }
433 
434  } // end TalkingWithProxy
435 
436 
437 
438 
439