1 //////////////////////////////////////////////////////////////////////////////
2 //                            DX SOURCEFILE        //
3 //////////////////////////////////////////////////////////////////////////////
4 
5 /*
6  * $Header: /src/master/dx/src/uipp/java/dx/client/AppletClient.java,v 1.3 2005/12/26 21:33:42 davidt Exp $
7  */
8 
9 /*
10  *
11  */
12 
13 package dx.client;
14 import java.applet.*;
15 import java.awt.*;
16 import java.net.*;
17 import java.io.*;
18 import java.util.*;
19 
20 
21 //
22 //
23 //
24 
25 public abstract class AppletClient extends Applet
26 {
27 
update( Graphics g )28     public void update( Graphics g )
29     {
30         paint( g );
31     }
32 
33     //
34     // Overriding these gives subclasses a way to control behavior without
35     // implementing loading logic.
36     //
getCurrentImage()37     protected Image getCurrentImage()
38     {
39         return current_image;
40     }
41 
getCurrentSequence()42     protected int getCurrentSequence()
43     {
44         return current_sequence;
45     }
46 
getCurrentLoop()47     protected int getCurrentLoop()
48     {
49         return current_iteration;
50     }
51 
getImageHandling()52     protected boolean getImageHandling()
53     {
54         return true;
55     }
56 
getIsEmbedded()57     protected boolean getIsEmbedded()
58     {
59         return false;
60     }
61 
getNextIter( int i )62     protected int getNextIter( int i )
63     {
64         return i + 1;
65     }
66 
loadNextImage()67     protected boolean loadNextImage()
68     {
69         return initial_loading;
70     }
71 
isLoopValid( String gifname, int s, int l )72     protected boolean isLoopValid( String gifname, int s, int l )
73     {
74         if ( s < current_sequence ) return false;
75 
76         if ( s > current_sequence ) return true;
77 
78         return ( l >= current_iteration );
79     }
80 
setCurrentImage( Image i, int s, int l )81     protected synchronized void setCurrentImage( Image i, int s, int l )
82     {
83         current_image = i; current_sequence = s; current_iteration = l;
84     }
85 
86 
87     private Image current_image;
88     private Vector fclts;
89     private String gifname;
90     private String mostRecentUrl;
91     private int current_iteration;
92     private int current_sequence;
93 
getImageUrl()94     protected String getImageUrl()
95     {
96         return this.mostRecentUrl;
97     }
98 
99     //
100     // Set to true when initializing so that we'll look for each iteration
101     // of a loop.  When running, we'll receive a notification for each iteration.
102     //
103     private boolean initial_loading;
104 
AppletClient()105     protected AppletClient()
106     {
107         super();
108         gifname = null;
109         mostRecentUrl = null;
110         current_image = null;
111         current_iteration = 0;
112         fclts = new Vector( 4 );
113     }
114 
init()115     public void init()
116     {
117         super.init();
118         fclts.removeAllElements();
119 
120         gifname = getParameter( "INITIAL_IMAGE" );
121 
122         //
123         // If our URL indicates a non-zero loop count then start loading
124         // images earlier in the sequence.
125         // Look for %s_%d.%d.%d.*
126         //
127         initial_loading = true;
128 
129         if ( getIsEmbedded() == false ) {
130             current_sequence = 0;
131 
132             if ( getLoopCount( gifname ) > 0 ) {
133                 String s = getImageName( gifname, 0 );
134                 requestImage ( s, 0, 0 );
135             }
136 
137             else {
138                 requestImage ( gifname, 0, 0 );
139             }
140 
141             repaint();
142         }
143     }
144 
stop()145     public void stop()
146     {
147         super.stop();
148         Enumeration enum1 = this.fclts.elements();
149 
150         while ( enum1.hasMoreElements() ) {
151             AppletLoadThread fclt = ( AppletLoadThread ) enum1.nextElement();
152 
153             if ( ( fclt != null ) && ( fclt.isAlive() ) )
154                 fclt.interrupt();
155         }
156 
157         this.fclts.removeAllElements();
158     }
159 
160     //
161     // This is called in async fashion by AppletLoadThread.
162     // It's possible to have 2 threads running.
163     // The locking is to protect current_image.
164     //
165 
imageAvailable( Image i, String s, int sequence, int loop, String urlString )166     public synchronized void imageAvailable
167     ( Image i, String s, int sequence, int loop, String urlString )
168     {
169         if ( isLoopValid( s, sequence, loop ) == false ) return ;
170 
171         //
172         // There isn't any way of knowing if another frame is available.
173         // So we just have to go looking for it in the case where we're
174         // just starting up.
175         //
176         if ( i != null ) {
177             if ( loadNextImage() ) {
178                 int cnt = getNextIter( loop );
179                 String gn = getImageName ( s, cnt );
180                 requestImage( gn, sequence, cnt );
181             }
182 
183             if ( sequence > current_sequence ) {
184                 Enumeration enum1 = fclts.elements();
185                 Vector deceased = new Vector( 4 );
186 
187                 while ( enum1.hasMoreElements() ) {
188                     AppletLoadThread fclt = ( AppletLoadThread ) enum1.nextElement();
189 
190                     if ( ( fclt != null ) && ( fclt.getSequence() < sequence ) ) {
191                         if ( fclt.isAlive() )
192                         	fclt.interrupt();
193 
194                         deceased.addElement( ( Object ) fclt );
195                     }
196 
197                     else if ( ( fclt != null ) && ( fclt.isAlive() == false ) ) {
198                         deceased.addElement( ( Object ) fclt );
199                     }
200                 }
201 
202                 enum1 = deceased.elements();
203 
204                 while ( enum1.hasMoreElements() ) {
205                     AppletLoadThread fclt = ( AppletLoadThread ) enum1.nextElement();
206                     fclts.removeElement( ( Object ) fclt );
207                 }
208             }
209 
210             this.mostRecentUrl = urlString;
211             setCurrentImage( i, sequence, loop );
212         }
213 
214         else {
215             if ( initial_loading == false ) {
216                 System.out.println ( "AppletClient: couldn't load " + s );
217             }
218 
219             else {
220                 initial_loading = false;
221                 current_sequence = -1;
222             }
223         }
224 
225         if ( i != null )
226             repaint();
227     }
228 
requestImage( String gifname, int sequence, int loop )229     protected void requestImage ( String gifname, int sequence, int loop )
230     {
231         AppletLoadThread fclt = new AppletLoadThread( this, gifname, sequence, loop );
232         fclt.start();
233         fclts.addElement( ( Object ) fclt );
234     }
235 
requestImage( String gifname )236     protected void requestImage ( String gifname )
237     {
238         int seq = getSequenceCount( gifname );
239         int loop = getLoopCount( gifname );
240         requestImage( gifname, seq, loop );
241     }
242 
paint( Graphics g )243     public void paint( Graphics g )
244     {
245         if ( getIsEmbedded() == false ) {
246             Dimension d = getSize();
247 
248             if ( getCurrentImage() == null ) {
249                 g.setColor ( Color.black );
250                 g.fillRect ( 0, 0, d.width, d.height );
251             }
252 
253             else {
254                 Image im = getCurrentImage();
255                 g.drawImage( im, 0, 0, d.width, d.height, Color.black, this );
256             }
257         }
258     }
259 
260     //
261     // Pull the loop counter out of the image name
262     // The name looks like: foobar1.0.0.htm or
263     // 1_1.0.0.htm
264     //
getLoopCount( String s )265     protected int getLoopCount( String s )
266     {
267         int slash = s.lastIndexOf( ( int ) /*File.separatorChar*/'/' );
268         String basename;
269 
270         if ( slash >= 0 )
271             basename = s.substring( slash + 1 );
272         else
273             basename = s;
274 
275         StringTokenizer stok = new StringTokenizer( basename, "." );
276 
277         int loop = 0;
278 
279         boolean loop_found = false;
280 
281         int tokens = 0;
282 
283         boolean parse_error = false;
284 
285         while ( ( parse_error == false ) && ( loop_found == false ) && ( stok.hasMoreTokens() ) ) {
286             String tok = stok.nextToken();
287 
288             switch ( tokens ) {
289             case 0:
290                 break;
291             case 1:
292 
293                 try {
294                     Integer jidi = new Integer( tok );
295                     int jid = jidi.intValue();
296                 }
297 
298                 catch ( Exception e ) {
299                     parse_error = true;
300                 }
301 
302                 break;
303             case 2:
304 
305                 try {
306                     Integer loopi = new Integer( tok );
307                     loop = loopi.intValue();
308                     loop_found = true;
309                 }
310 
311                 catch ( Exception e ) {
312                     parse_error = true;
313                 }
314 
315                 break;
316             default:
317                 parse_error = true;
318                 break;
319             }
320 
321             tokens++;
322         }
323 
324         if ( loop_found )
325             return loop;
326 
327         initial_loading = false;
328 
329         return -1;
330     }
331 
getSequenceCount( String s )332     protected int getSequenceCount( String s )
333     {
334         int slash = s.lastIndexOf( ( int ) /*File.separatorChar*/'/' );
335         String basename;
336 
337         if ( slash >= 0 )
338             basename = s.substring( slash + 1 );
339         else
340             basename = s;
341 
342         StringTokenizer stok = new StringTokenizer( basename, "." );
343 
344         int seq = 0;
345 
346         boolean seq_found = false;
347 
348         int tokens = 0;
349 
350         boolean parse_error = false;
351 
352         while ( ( parse_error == false ) && ( seq_found == false ) && ( stok.hasMoreTokens() ) ) {
353             String tok = stok.nextToken();
354 
355             switch ( tokens ) {
356             case 0:
357                 break;
358             case 1:
359 
360                 try {
361                     Integer seqi = new Integer( tok );
362                     seq = seqi.intValue();
363                     seq_found = true;
364                 }
365 
366                 catch ( Exception e ) {
367                     parse_error = true;
368                 }
369 
370                 break;
371             default:
372                 parse_error = true;
373                 break;
374             }
375 
376             tokens++;
377         }
378 
379         if ( seq_found )
380             return seq;
381 
382         initial_loading = false;
383 
384         return -1;
385     }
386 
getImageName( String gifname, int loop )387     protected String getImageName( String gifname, int loop )
388     {
389         int oldloop = getLoopCount( gifname );
390 
391         int slash = gifname.lastIndexOf( ( int ) /*File.separatorChar*/'/' );
392         String basename;
393         String fullPath;
394 
395         if ( slash >= 0 ) {
396             basename = gifname.substring( slash + 1 );
397             fullPath = gifname.substring( 0, slash + 1 );
398         }
399 
400         else {
401             basename = gifname;
402             fullPath = null;
403         }
404 
405         StringTokenizer stok = new StringTokenizer( basename, "." );
406         boolean loop_found = false;
407         int tokens = 0;
408         boolean parse_error = false;
409 
410         while ( ( parse_error == false ) && ( loop_found == false ) && ( stok.hasMoreTokens() ) ) {
411             String tok = stok.nextToken();
412 
413             switch ( tokens ) {
414             case 0:
415 
416                 if ( fullPath == null ) fullPath = tok;
417                 else fullPath = fullPath + tok;
418 
419                 break;
420 
421             case 1:
422                 fullPath = fullPath + "." + tok;
423 
424                 break;
425 
426             case 2:
427                 fullPath = fullPath + "." + loop;
428 
429                 break;
430 
431             default:
432                 fullPath = fullPath + "." + tok;
433 
434                 break;
435             }
436 
437             tokens++;
438         }
439 
440         return fullPath;
441     }
442 
443 
444 } // end AppletClient
445 
446 
447