1 package org.kde.kjas.server; 2 3 import java.io.*; 4 import java.util.*; 5 import java.awt.*; 6 import java.net.*; 7 8 /** 9 * Encapsulates the KJAS protocol and manages the contexts 10 * 11 */ 12 public class KJASProtocolHandler 13 { 14 // Command codes- always need to be synced up with 15 // what's in kjavaappletserver.cpp 16 private static final int CreateContextCode = 1; 17 private static final int DestroyContextCode = 2; 18 private static final int CreateAppletCode = 3; 19 private static final int DestroyAppletCode = 4; 20 private static final int StartAppletCode = 5; 21 private static final int StopAppletCode = 6; 22 private static final int InitAppletCode = 7; 23 private static final int ShowDocumentCode = 8; 24 private static final int ShowURLInFrameCode = 9; 25 private static final int ShowStatusCode = 10; 26 private static final int ResizeAppletCode = 11; 27 private static final int GetURLDataCode = 12; 28 private static final int URLDataCode = 13; 29 private static final int ShutdownServerCode = 14; 30 private static final int JavaScriptEvent = 15; 31 static final int GetMember = 16; 32 static final int CallMember = 17; 33 private static final int PutMember = 18; 34 private static final int DerefObject = 19; 35 36 private static final int AudioClipPlayCode = 20; 37 private static final int AudioClipLoopCode = 21; 38 private static final int AudioClipStopCode = 22; 39 40 private static final int AppletStateNotificationCode = 23; 41 private static final int AppletFailedCode = 24; 42 private static final int DataCommand = 25; 43 private static final int PutURLDataCode = 26; 44 private static final int PutDataCode = 27; 45 private static final int SecurityConfirmCode = 28; 46 private static final int ShowConsole = 29; 47 48 //Holds contexts in contextID-context pairs 49 private Hashtable contexts; 50 51 private PushbackInputStream commands; //Stream for reading in commands 52 private PrintStream signals; //Stream for writing out callbacks 53 54 //used for parsing each command as it comes in 55 private int cmd_index; 56 private final static char sep = (char) 0; 57 KJASProtocolHandler( InputStream _commands, OutputStream _signals )58 public KJASProtocolHandler( InputStream _commands, 59 OutputStream _signals ) 60 { 61 commands = new PushbackInputStream( _commands ); 62 signals = new PrintStream( _signals ); 63 contexts = new Hashtable(); 64 } 65 commandLoop()66 public void commandLoop() 67 { 68 try 69 { 70 while( true ) 71 { 72 try 73 { 74 int cmd_length = readPaddedLength( 8 ); 75 Main.debug( "PH: cmd_length = " + cmd_length ); 76 77 //We need to have this while loop since we're not guaranteed to get 78 //all the bytes we want back, especially with large jars 79 byte[] cmd_data = new byte[cmd_length]; 80 int total_read = 0; 81 while( total_read < cmd_length ) 82 { 83 int numread = commands.read( cmd_data, total_read, cmd_length-total_read ); 84 Main.debug( "PH: read in " + numread + " bytes for command" ); 85 total_read += numread; 86 } 87 88 //parse the rest of the command and execute it 89 processCommand( cmd_data ); 90 } 91 catch( NumberFormatException e ) 92 { 93 Main.kjas_err( "Could not parse out message length", e ); 94 e.printStackTrace(); 95 System.exit( 1 ); 96 } 97 catch( Throwable t ) 98 { 99 Main.debug( "commandLoop caught a throwable, still going" ); 100 t.printStackTrace(); 101 } 102 } 103 } 104 catch( Exception i ) 105 { 106 Main.kjas_err( "commandLoop exited on exception: ", i ); 107 i.printStackTrace(); 108 System.exit( 1 ); 109 } 110 } 111 processCommand( byte[] command )112 public void processCommand( byte[] command ) 113 { 114 // Sanity checks 115 if ( command == null ) 116 return; 117 118 //do all the parsing here and pass arguments as individual variables to the 119 //handler functions 120 int cmd_length = command.length; 121 cmd_index = 0; 122 123 int cmd_code_value = (int) command[cmd_index++]; 124 if( cmd_code_value == CreateContextCode ) 125 { 126 //parse out contextID- 1 argument 127 String contextID = getArg( command ); 128 Main.debug( "createContext, id = " + contextID ); 129 130 KJASAppletContext context = new KJASAppletContext( contextID ); 131 contexts.put( contextID, context ); 132 } else 133 if( cmd_code_value == DestroyContextCode ) 134 { 135 //parse out contextID- 1 argument 136 String contextID = getArg( command ); 137 Main.debug( "destroyContext, id = " + contextID ); 138 139 KJASAppletContext context = (KJASAppletContext) contexts.get( contextID ); 140 if( contexts != null ) 141 { 142 context.destroy(); 143 contexts.remove( contextID ); 144 } 145 } else 146 if( cmd_code_value == CreateAppletCode ) 147 { 148 //9 arguments- this order is important... 149 final String contextID = getArg( command ); 150 final String appletID = getArg( command ); 151 final String appletName = getArg( command ); 152 final String className = getArg( command ); 153 final String baseURL = getArg( command ); 154 final String username = getArg( command ); 155 final String password = getArg( command ); 156 final String authname = getArg( command ); 157 final String codeBase = getArg( command ); 158 final String archives = getArg( command ); 159 final String width = getArg( command ); 160 final String height = getArg( command ); 161 final String title = getArg( command ); 162 163 //get the number of parameter pairs... 164 String str_params = getArg( command ); 165 int num_params = Integer.parseInt( str_params.trim() ); 166 final Hashtable params = new Hashtable(); 167 for( int i = 0; i < num_params; i++ ) 168 { 169 String name = getArg( command ); // note name is in uppercase 170 if( name == null ) 171 name = new String(); 172 173 String value = getArg( command ); 174 if( value == null ) 175 value = new String(); 176 params.put( name, value ); 177 //Main.debug( "parameter, name = " + name + ", value = " + value ); 178 } 179 180 Main.debug( "createApplet, context = " + contextID + ", applet = " + appletID ); 181 Main.debug( " name = " + appletName + ", classname = " + className ); 182 Main.debug( " baseURL = " + baseURL + ", codeBase = " + codeBase ); 183 Main.debug( " archives = " + archives + ", width = " + width + 184 ", height = " + height ); 185 186 final KJASAppletContext context = (KJASAppletContext) contexts.get( contextID ); 187 if( context != null ) 188 { 189 context.createApplet( appletID, appletName, className, 190 baseURL, username, password, authname, 191 codeBase, archives, 192 width, height, title, params ); 193 } 194 195 } else 196 if( cmd_code_value == DestroyAppletCode ) 197 { 198 //2 arguments 199 String contextID = getArg( command ); 200 String appletID = getArg( command ); 201 Main.debug( "destroyApplet, context = " + contextID + ", applet = " + appletID ); 202 203 KJASAppletContext context = (KJASAppletContext) contexts.get( contextID ); 204 if ( context != null ) 205 context.destroyApplet( appletID ); 206 } else 207 if( cmd_code_value == StartAppletCode ) 208 { 209 //2 arguments 210 String contextID = getArg( command ); 211 String appletID = getArg( command ); 212 Main.debug( "startApplet, context = " + contextID + ", applet = " + appletID ); 213 214 KJASAppletContext context = (KJASAppletContext) contexts.get( contextID ); 215 if ( context != null ) 216 context.startApplet( appletID ); 217 } else 218 if( cmd_code_value == StopAppletCode ) 219 { 220 //2 arguments 221 String contextID = getArg( command ); 222 String appletID = getArg( command ); 223 Main.debug( "stopApplet, context = " + contextID + ", applet = " + appletID ); 224 225 KJASAppletContext context = (KJASAppletContext) contexts.get( contextID ); 226 if ( context != null ) 227 context.stopApplet( appletID ); 228 } else 229 if( cmd_code_value == ShutdownServerCode ) 230 { 231 Main.debug( "shutDownServer received" ); 232 KJASAppletStub.waitForAppletThreads(); 233 System.exit( 1 ); 234 } 235 else 236 if( cmd_code_value == URLDataCode ) 237 { 238 239 String id = getArg( command ); 240 String code = getArg( command ); 241 Main.debug( "KIO URLData received(" + id + ") code:" + code ); 242 243 //rest of the command should be the data... 244 byte[] data = null; 245 if (cmd_length - cmd_index > 0) { 246 data = new byte[ cmd_length - cmd_index ]; 247 System.arraycopy( command, cmd_index, data, 0, data.length ); 248 } 249 KIOConnection.setData(id, Integer.parseInt(code), data); 250 } else 251 if (cmd_code_value == GetMember) 252 { 253 int ticketnr = Integer.parseInt( getArg( command ) ); 254 String contextID = getArg( command ); 255 String appletID = getArg( command ); 256 int objid = Integer.parseInt( getArg( command ) ); 257 String name = getArg( command ); 258 KJASAppletContext context = (KJASAppletContext) contexts.get( contextID ); 259 if ( context == null || !context.getMember(appletID, ticketnr, objid, name)) 260 sendMemberValue(contextID, GetMember, ticketnr, -1, 0, ""); 261 } else 262 if (cmd_code_value == PutMember) 263 { 264 int ticketnr = Integer.parseInt( getArg( command ) ); 265 String contextID = getArg( command ); 266 String appletID = getArg( command ); 267 int objid = Integer.parseInt( getArg( command ) ); 268 String name = getArg( command ); 269 String value = getArg( command ); 270 boolean ret = false; 271 KJASAppletContext context = (KJASAppletContext) contexts.get( contextID ); 272 if (context == null || !context.putMember(appletID, ticketnr, objid, name, value)) 273 sendPutMember(contextID, ticketnr, false); 274 } else 275 if (cmd_code_value == CallMember) 276 { 277 int ticketnr = Integer.parseInt( getArg( command ) ); 278 String contextID = getArg( command ); 279 String appletID = getArg( command ); 280 int objid = Integer.parseInt( getArg( command ) ); 281 String name = getArg( command ); 282 java.util.List args = new java.util.Vector(); 283 try { // fix getArg 284 String param = getArg(command); 285 while (param != null) { 286 args.add(param); 287 param = getArg(command); 288 } 289 } catch (Exception e) {} 290 291 KJASAppletContext context = (KJASAppletContext) contexts.get( contextID ); 292 if ( context == null || !context.callMember(appletID, ticketnr, objid, name, args)) 293 Main.protocol.sendMemberValue(contextID, CallMember, ticketnr, -1, 0, ""); 294 } else 295 if (cmd_code_value == DerefObject) 296 { 297 String contextID = getArg( command ); 298 String appletID = getArg( command ); 299 String objid = getArg( command ); 300 KJASAppletContext context = (KJASAppletContext) contexts.get( contextID ); 301 if ( context != null ) 302 context.derefObject(appletID, Integer.parseInt(objid)); 303 Main.debug( "DerefObject " + objid); 304 } else 305 if (cmd_code_value == SecurityConfirmCode) 306 { 307 String id = getArg( command ); 308 String confirm = getArg( command ); 309 Thread t = (Thread) KJASSecurityManager.confirmRequests.get(id); 310 Main.debug( "SecurityConfirmCode " + id + " confirm:" + confirm ); 311 if (t != null) { 312 KJASSecurityManager.confirmRequests.put(id, confirm); 313 try { 314 t.interrupt(); 315 } catch (SecurityException se) {} 316 } 317 } else 318 if (cmd_code_value == ShowConsole) 319 { 320 Main.console.setVisible(true); 321 } 322 else 323 { 324 throw new IllegalArgumentException( "Unknown command code" ); 325 } 326 } 327 328 /************************************************************** 329 ***** Methods for talking to the applet server ************** 330 **************************************************************/ 331 332 /** 333 * sends get url request 334 */ sendGetURLDataCmd( String jobid, String url )335 public void sendGetURLDataCmd( String jobid, String url ) 336 { 337 Main.debug( "sendGetURLCmd(" + jobid + ") url = " + url ); 338 //length = length of args plus 1 for code, 2 for seps and 1 for end 339 byte [] url_bytes = url.getBytes(); 340 int length = jobid.length() + url_bytes.length + 4; 341 byte [] bytes = new byte[ length + 8 ]; 342 byte [] tmp_bytes = getPaddedLengthBytes( length ); 343 int index = 0; 344 345 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 346 index += tmp_bytes.length; 347 bytes[index++] = (byte) GetURLDataCode; 348 bytes[index++] = sep; 349 350 tmp_bytes = jobid.getBytes(); 351 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 352 index += tmp_bytes.length; 353 bytes[index++] = sep; 354 355 System.arraycopy( url_bytes, 0, bytes, index, url_bytes.length ); 356 index += url_bytes.length; 357 bytes[index++] = sep; 358 359 signals.write( bytes, 0, bytes.length ); 360 } 361 362 /** 363 * sends command for get url request (stop/hold/resume) or put (stop) 364 */ sendDataCmd( String id, int cmd )365 public void sendDataCmd( String id, int cmd ) 366 { 367 Main.debug( "sendDataCmd(" + id + ") command = " + cmd ); 368 byte [] cmd_bytes = String.valueOf( cmd ).getBytes(); 369 int length = id.length() + cmd_bytes.length + 4; 370 byte [] bytes = new byte[ length + 8 ]; 371 byte [] tmp_bytes = getPaddedLengthBytes( length ); 372 int index = 0; 373 374 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 375 index += tmp_bytes.length; 376 bytes[index++] = (byte) DataCommand; 377 bytes[index++] = sep; 378 379 tmp_bytes = id.getBytes(); 380 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 381 index += tmp_bytes.length; 382 bytes[index++] = sep; 383 384 System.arraycopy( cmd_bytes, 0, bytes, index, cmd_bytes.length ); 385 index += cmd_bytes.length; 386 bytes[index++] = sep; 387 388 signals.write( bytes, 0, bytes.length ); 389 } 390 /** 391 * sends put url request 392 */ sendPutURLDataCmd( String jobid, String url )393 public void sendPutURLDataCmd( String jobid, String url ) 394 { 395 Main.debug( "sendPutURLCmd(" + jobid + ") url = " + url ); 396 //length = length of args plus 1 for code, 2 for seps and 1 for end 397 byte [] url_bytes = url.getBytes(); 398 int length = jobid.length() + url_bytes.length + 4; 399 byte [] bytes = new byte[ length + 8 ]; 400 byte [] tmp_bytes = getPaddedLengthBytes( length ); 401 int index = 0; 402 403 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 404 index += tmp_bytes.length; 405 bytes[index++] = (byte) PutURLDataCode; 406 bytes[index++] = sep; 407 408 tmp_bytes = jobid.getBytes(); 409 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 410 index += tmp_bytes.length; 411 bytes[index++] = sep; 412 413 System.arraycopy( url_bytes, 0, bytes, index, url_bytes.length ); 414 index += url_bytes.length; 415 bytes[index++] = sep; 416 417 signals.write( bytes, 0, bytes.length ); 418 } 419 /** 420 * sends put data 421 */ sendPutData( String jobid, byte [] b, int off, int len )422 public void sendPutData( String jobid, byte [] b, int off, int len ) 423 { 424 Main.debug( "sendPutData(" + jobid + ") len = " + len ); 425 //length = length of args plus 1 for code, 2 for seps and 1 for end 426 int length = jobid.length() + len + 4; 427 byte [] bytes = new byte[ length + 8 ]; 428 byte [] tmp_bytes = getPaddedLengthBytes( length ); 429 int index = 0; 430 431 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 432 index += tmp_bytes.length; 433 bytes[index++] = (byte) PutDataCode; 434 bytes[index++] = sep; 435 436 tmp_bytes = jobid.getBytes(); 437 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 438 index += tmp_bytes.length; 439 bytes[index++] = sep; 440 441 System.arraycopy( b, off, bytes, index, len ); 442 index += len; 443 bytes[index++] = sep; 444 445 signals.write( bytes, 0, bytes.length ); 446 } 447 /** 448 * sends notification about the state of the applet. 449 * @see org.kde.kjas.server.KJASAppletStub for valid states 450 */ sendAppletStateNotification( String contextID, String appletID, int state )451 public void sendAppletStateNotification( String contextID, String appletID, int state ) 452 { 453 Main.debug( "sendAppletStateNotification, contextID = " + contextID + ", appletID = " + 454 appletID + ", state=" + state ); 455 456 byte [] state_bytes = String.valueOf( state ).getBytes(); 457 458 int length = contextID.length() + appletID.length() + state_bytes.length + 5; 459 byte [] bytes = new byte[ length + 8 ]; //for length of message 460 byte [] tmp_bytes = getPaddedLengthBytes( length ); 461 int index = 0; 462 463 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 464 index += tmp_bytes.length; 465 bytes[index++] = (byte) AppletStateNotificationCode; 466 bytes[index++] = sep; 467 468 tmp_bytes = contextID.getBytes(); 469 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 470 index += tmp_bytes.length; 471 bytes[index++] = sep; 472 473 tmp_bytes = appletID.getBytes(); 474 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 475 index += tmp_bytes.length; 476 bytes[index++] = sep; 477 478 System.arraycopy( state_bytes, 0, bytes, index, state_bytes.length ); 479 index += state_bytes.length; 480 bytes[index++] = sep; 481 482 signals.write( bytes, 0, bytes.length ); 483 } 484 485 /** 486 * sends notification about applet failure. 487 * This can happen in any state. 488 * @param contextID context ID of the applet's context 489 * @param appletID ID of the applet 490 * @param errorMessage any message 491 */ sendAppletFailed( String contextID, String appletID, String errorMessage)492 public void sendAppletFailed ( String contextID, String appletID, String errorMessage) 493 { 494 Main.debug( "sendAppletFailed, contextID = " + contextID + ", appletID = " + 495 appletID + ", errorMessage=" + errorMessage ); 496 byte [] msg_bytes = errorMessage.getBytes(); 497 int length = contextID.length() + appletID.length() + msg_bytes.length + 5; 498 byte [] bytes = new byte[ length + 8 ]; //for length of message 499 byte [] tmp_bytes = getPaddedLengthBytes( length ); 500 int index = 0; 501 502 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 503 index += tmp_bytes.length; 504 bytes[index++] = (byte) AppletFailedCode; 505 bytes[index++] = sep; 506 507 tmp_bytes = contextID.getBytes(); 508 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 509 index += tmp_bytes.length; 510 bytes[index++] = sep; 511 512 tmp_bytes = appletID.getBytes(); 513 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 514 index += tmp_bytes.length; 515 bytes[index++] = sep; 516 517 System.arraycopy( msg_bytes, 0, bytes, index, msg_bytes.length ); 518 index += msg_bytes.length; 519 bytes[index++] = sep; 520 521 signals.write( bytes, 0, bytes.length ); 522 } 523 sendShowDocumentCmd( String loaderKey, String url )524 public void sendShowDocumentCmd( String loaderKey, String url ) 525 { 526 Main.debug( "sendShowDocumentCmd from context#" + loaderKey + " url = " + url ); 527 528 //length = length of args + 2 for seps + 1 for end + 1 for code 529 byte [] url_bytes = url.getBytes(); 530 byte [] key_bytes = loaderKey.getBytes(); 531 int length = key_bytes.length + url_bytes.length + 4; 532 byte [] bytes = new byte[ length + 8 ]; //8 for the length of this message 533 byte [] tmp_bytes = getPaddedLengthBytes( length ); 534 int index = 0; 535 536 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 537 index += tmp_bytes.length; 538 bytes[index++] = (byte) ShowDocumentCode; 539 bytes[index++] = sep; 540 541 System.arraycopy( key_bytes, 0, bytes, index, key_bytes.length ); 542 index += key_bytes.length; 543 bytes[index++] = sep; 544 545 System.arraycopy( url_bytes, 0, bytes, index, url_bytes.length ); 546 index += url_bytes.length; 547 bytes[index++] = sep; 548 549 signals.write( bytes, 0, bytes.length ); 550 } 551 sendShowDocumentCmd( String contextID, String url, String frame)552 public void sendShowDocumentCmd( String contextID, String url, String frame) 553 { 554 Main.debug( "sendShowDocumentCmd from context#" + contextID + 555 " url = " + url + ", frame = " + frame ); 556 557 //length = length of args plus code, 3 seps, end 558 byte [] url_bytes = url.getBytes(); 559 byte [] frame_bytes = frame.getBytes(); 560 int length = contextID.length() + url_bytes.length + frame_bytes.length + 5; 561 byte [] bytes = new byte[ length + 8 ]; //for length of message 562 byte [] tmp_bytes = getPaddedLengthBytes( length ); 563 int index = 0; 564 565 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 566 index += tmp_bytes.length; 567 bytes[index++] = (byte) ShowURLInFrameCode; 568 bytes[index++] = sep; 569 570 tmp_bytes = contextID.getBytes(); 571 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 572 index += tmp_bytes.length; 573 bytes[index++] = sep; 574 575 System.arraycopy( url_bytes, 0, bytes, index, url_bytes.length ); 576 index += url_bytes.length; 577 bytes[index++] = sep; 578 579 System.arraycopy( frame_bytes, 0, bytes, index, frame_bytes.length ); 580 index += frame_bytes.length; 581 bytes[index++] = sep; 582 583 signals.write( bytes, 0, bytes.length ); 584 } 585 sendShowStatusCmd( String contextID, String msg )586 public void sendShowStatusCmd( String contextID, String msg ) 587 { 588 Main.debug( "sendShowStatusCmd, contextID = " + contextID + " msg = " + msg ); 589 590 byte [] msg_bytes = msg.getBytes(); 591 int length = contextID.length() + msg_bytes.length + 4; 592 byte [] bytes = new byte[ length + 8 ]; //for length of message 593 int index = 0; 594 595 byte [] tmp_bytes = getPaddedLengthBytes( length ); 596 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 597 index += tmp_bytes.length; 598 bytes[index++] = (byte) ShowStatusCode; 599 bytes[index++] = sep; 600 601 tmp_bytes = contextID.getBytes(); 602 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 603 index += tmp_bytes.length; 604 bytes[index++] = sep; 605 606 System.arraycopy( msg_bytes, 0, bytes, index, msg_bytes.length ); 607 index += msg_bytes.length; 608 bytes[index++] = sep; 609 610 signals.write( bytes, 0, bytes.length ); 611 } 612 sendResizeAppletCmd( String contextID, String appletID, int width, int height )613 public void sendResizeAppletCmd( String contextID, String appletID, 614 int width, int height ) 615 { 616 Main.debug( "sendResizeAppletCmd, contextID = " + contextID + ", appletID = " + 617 appletID + ", width = " + width + ", height = " + height ); 618 619 byte [] width_bytes = String.valueOf( width ).getBytes(); 620 byte [] height_bytes = String.valueOf( height ).getBytes(); 621 622 //length = length of args plus code, 4 seps, end 623 int length = contextID.length() + appletID.length() + width_bytes.length + 624 height_bytes.length + 6; 625 byte [] bytes = new byte[ length + 8 ]; //for length of message 626 byte [] tmp_bytes = getPaddedLengthBytes( length ); 627 int index = 0; 628 629 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 630 index += tmp_bytes.length; 631 bytes[index++] = (byte) ResizeAppletCode; 632 bytes[index++] = sep; 633 634 tmp_bytes = contextID.getBytes(); 635 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 636 index += tmp_bytes.length; 637 bytes[index++] = sep; 638 639 tmp_bytes = appletID.getBytes(); 640 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 641 index += tmp_bytes.length; 642 bytes[index++] = sep; 643 644 System.arraycopy( width_bytes, 0, bytes, index, width_bytes.length ); 645 index += width_bytes.length; 646 bytes[index++] = sep; 647 648 System.arraycopy( height_bytes, 0, bytes, index, height_bytes.length ); 649 index += height_bytes.length; 650 bytes[index++] = sep; 651 652 signals.write( bytes, 0, bytes.length ); 653 } sendJavaScriptEventCmd( String contextID, String appletID, int objid, String event, int [] types, String [] args )654 public void sendJavaScriptEventCmd( String contextID, String appletID, int objid, String event, int [] types, String [] args ) 655 { 656 Main.debug( "sendJavaScriptEventCmd, contextID = " + contextID + " event = " + event ); 657 String objstr = new String("" + objid); 658 int length = contextID.length() + appletID.length() + event.length() + objstr.length() + 6; 659 byte [][][] arglist = null; 660 if (types != null) { 661 arglist = new byte[args.length][2][]; 662 for (int i = 0; i < types.length; i++) { 663 arglist[i][0] = (new String("" + types[i])).getBytes(); 664 arglist[i][1] = args[i].getBytes(); 665 length += 2 + arglist[i][0].length + arglist[i][1].length; 666 } 667 } 668 byte [] bytes = new byte[ length + 8 ]; //for length of message 669 int index = 0; 670 671 byte [] tmp_bytes = getPaddedLengthBytes( length ); 672 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 673 index += tmp_bytes.length; 674 bytes[index++] = (byte) JavaScriptEvent; 675 bytes[index++] = sep; 676 677 tmp_bytes = contextID.getBytes(); 678 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 679 index += tmp_bytes.length; 680 bytes[index++] = sep; 681 682 tmp_bytes = appletID.getBytes(); 683 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 684 index += tmp_bytes.length; 685 bytes[index++] = sep; 686 687 tmp_bytes = objstr.getBytes(); 688 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 689 index += tmp_bytes.length; 690 bytes[index++] = sep; 691 692 tmp_bytes = event.getBytes(); 693 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 694 index += tmp_bytes.length; 695 bytes[index++] = sep; 696 697 if (types != null) 698 for (int i = 0; i < types.length; i++) { 699 System.arraycopy( arglist[i][0], 0, bytes, index, arglist[i][0].length ); 700 index += arglist[i][0].length; 701 bytes[index++] = sep; 702 System.arraycopy( arglist[i][1], 0, bytes, index, arglist[i][1].length ); 703 index += arglist[i][1].length; 704 bytes[index++] = sep; 705 } 706 707 signals.write( bytes, 0, bytes.length ); 708 } sendMemberValue( String contextID, int cmd, int ticketnr, int type, int rid, String value )709 public void sendMemberValue( String contextID, int cmd, int ticketnr, int type, int rid, String value ) 710 { 711 Main.debug( "sendMemberValue, contextID = " + contextID + " value = " + value + " type=" + type + " rid=" + rid ); 712 713 String strticket = String.valueOf( ticketnr ); 714 String strtype = String.valueOf( type ); 715 String strobj = String.valueOf( rid ); 716 byte [] value_bytes = value.getBytes(); 717 int length = contextID.length() + value_bytes.length + strtype.length() + strobj.length() + strticket.length() + 7; 718 byte [] bytes = new byte[ length + 8 ]; //for length of message 719 int index = 0; 720 721 byte [] tmp_bytes = getPaddedLengthBytes( length ); 722 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 723 index += tmp_bytes.length; 724 bytes[index++] = (byte) cmd; 725 bytes[index++] = sep; 726 727 tmp_bytes = contextID.getBytes(); 728 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 729 index += tmp_bytes.length; 730 bytes[index++] = sep; 731 732 tmp_bytes = strticket.getBytes(); 733 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 734 index += tmp_bytes.length; 735 bytes[index++] = sep; 736 737 tmp_bytes = strtype.getBytes(); 738 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 739 index += tmp_bytes.length; 740 bytes[index++] = sep; 741 742 tmp_bytes = strobj.getBytes(); 743 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 744 index += tmp_bytes.length; 745 bytes[index++] = sep; 746 747 System.arraycopy( value_bytes, 0, bytes, index, value_bytes.length ); 748 index += value_bytes.length; 749 bytes[index++] = sep; 750 751 signals.write( bytes, 0, bytes.length ); 752 } 753 sendAudioClipCommand(String contextId, String url, int cmd)754 private void sendAudioClipCommand(String contextId, String url, int cmd) { 755 byte [] url_bytes = url.getBytes(); 756 int length = contextId.length() + url_bytes.length + 4; 757 byte [] bytes = new byte[ length + 8 ]; 758 byte [] tmp_bytes = getPaddedLengthBytes( length ); 759 int index = 0; 760 761 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 762 index += tmp_bytes.length; 763 bytes[index++] = (byte) cmd; 764 bytes[index++] = sep; 765 766 tmp_bytes = contextId.getBytes(); 767 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 768 index += tmp_bytes.length; 769 bytes[index++] = sep; 770 771 System.arraycopy( url_bytes, 0, bytes, index, url_bytes.length ); 772 index += url_bytes.length; 773 bytes[index++] = sep; 774 775 signals.write( bytes, 0, bytes.length ); 776 } 777 sendAudioClipPlayCommand(String contextId, String url)778 public void sendAudioClipPlayCommand(String contextId, String url) { 779 sendAudioClipCommand(contextId, url, AudioClipPlayCode); 780 } sendAudioClipLoopCommand(String contextId, String url)781 public void sendAudioClipLoopCommand(String contextId, String url) { 782 sendAudioClipCommand(contextId, url, AudioClipLoopCode); 783 } sendAudioClipStopCommand(String contextId, String url)784 public void sendAudioClipStopCommand(String contextId, String url) { 785 sendAudioClipCommand(contextId, url, AudioClipStopCode); 786 } 787 sendPutMember( String contextID, int ticketnr, boolean success )788 public void sendPutMember( String contextID, int ticketnr, boolean success ) 789 { 790 Main.debug("sendPutMember, contextID = " + contextID + " success = " + success); 791 792 byte [] ticket_bytes = String.valueOf( ticketnr ).getBytes(); 793 byte [] ret_bytes = String.valueOf( success ? "1" : "0" ).getBytes(); 794 int length = contextID.length() + ret_bytes.length + ticket_bytes.length + 5; 795 byte [] bytes = new byte[ length + 8 ]; //for length of message 796 byte [] tmp_bytes = getPaddedLengthBytes( length ); 797 int index = 0; 798 799 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 800 index += tmp_bytes.length; 801 bytes[index++] = (byte) PutMember; 802 bytes[index++] = sep; 803 804 tmp_bytes = contextID.getBytes(); 805 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 806 index += tmp_bytes.length; 807 bytes[index++] = sep; 808 809 System.arraycopy( ticket_bytes, 0, bytes, index, ticket_bytes.length ); 810 index += ticket_bytes.length; 811 bytes[index++] = sep; 812 813 System.arraycopy( ret_bytes, 0, bytes, index, ret_bytes.length ); 814 index += ret_bytes.length; 815 bytes[index++] = sep; 816 817 signals.write( bytes, 0, bytes.length ); 818 } sendSecurityConfirm( String [] certs, int certsnr, String perm, String id )819 public void sendSecurityConfirm( String [] certs, int certsnr, String perm, String id ) 820 { 821 Main.debug("sendSecurityConfirm, ID = " + id + " certsnr = " + certsnr); 822 823 byte [] id_bytes = id.getBytes(); 824 byte [] perm_bytes = perm.getBytes(); 825 byte [] certsnr_bytes = String.valueOf( certsnr ).getBytes(); 826 int length = perm_bytes.length + id_bytes.length + certsnr_bytes.length + 5; 827 for (int i = 0; i < certsnr; i++) 828 length += certs[i].length() + 1; 829 byte [] bytes = new byte[ length + 8 ]; //for length of message 830 byte [] tmp_bytes = getPaddedLengthBytes( length ); 831 int index = 0; 832 833 System.arraycopy( tmp_bytes, 0, bytes, index, tmp_bytes.length ); 834 index += tmp_bytes.length; 835 bytes[index++] = (byte) SecurityConfirmCode; 836 bytes[index++] = sep; 837 838 System.arraycopy( id_bytes, 0, bytes, index, id_bytes.length ); 839 index += id_bytes.length; 840 bytes[index++] = sep; 841 842 System.arraycopy( perm_bytes, 0, bytes, index, perm_bytes.length ); 843 index += perm_bytes.length; 844 bytes[index++] = sep; 845 846 System.arraycopy( certsnr_bytes, 0, bytes, index, certsnr_bytes.length ); 847 index += certsnr_bytes.length; 848 bytes[index++] = sep; 849 850 for (int i = 0; i < certsnr; i++) { 851 byte [] cert_bytes = certs[i].getBytes(); 852 System.arraycopy( cert_bytes, 0, bytes, index, cert_bytes.length ); 853 index += cert_bytes.length; 854 bytes[index++] = sep; 855 } 856 857 signals.write( bytes, 0, bytes.length ); 858 } 859 /************************************************************** 860 ***** Utility functions for parsing commands **************** 861 **************************************************************/ getArg( byte[] command )862 private String getArg( byte[] command ) 863 { 864 int begin = cmd_index; 865 while( 0 != ((int) command[cmd_index++]) ); 866 867 if( cmd_index > (begin + 1) ) 868 { 869 String rval = new String( command, begin, (cmd_index - begin - 1) ); 870 return rval; 871 } 872 else 873 return null; 874 } 875 getPaddedLengthBytes( int length )876 private byte[] getPaddedLengthBytes( int length ) 877 { 878 byte[] length_bytes = String.valueOf( length ).getBytes(); 879 if( length_bytes.length > 8 ) 880 throw new IllegalArgumentException( "can't create string number of length = 8" ); 881 byte [] bytes = { (byte) ' ', (byte) ' ', (byte) ' ', (byte) ' ', 882 (byte) ' ', (byte) ' ', (byte) ' ', (byte) ' '}; 883 System.arraycopy( length_bytes, 0, bytes, 0, length_bytes.length ); 884 return bytes; 885 } readPaddedLength( int string_size )886 private int readPaddedLength( int string_size ) 887 throws IOException 888 { 889 //read in 8 bytes for command length- length will be sent as a padded string 890 byte[] length = new byte[string_size]; 891 commands.read( length, 0, string_size ); 892 893 String length_str = new String( length ); 894 return Integer.parseInt( length_str.trim() ); 895 } 896 897 } 898