1 6 7 11 12 package org.openlaszlo.remote.soap.encoding; 13 14 import java.io.*; 15 import java.util.*; 16 import java.util.Iterator ; 17 18 import javax.xml.namespace.QName ; 19 import javax.xml.soap.Name ; 20 import javax.xml.soap.SOAPElement ; 21 22 import org.openlaszlo.server.LPS; 23 import org.openlaszlo.iv.flash.api.*; 24 import org.openlaszlo.iv.flash.api.action.*; 25 import org.openlaszlo.iv.flash.util.*; 26 import org.openlaszlo.remote.soap.LZSOAPUtils; 27 import org.openlaszlo.utils.ChainedException; 28 import org.openlaszlo.xml.internal.DataCommon; 29 import org.openlaszlo.xml.internal.DataContext; 30 import org.apache.axis.AxisFault; 31 import org.apache.log4j.Logger; 32 import org.xml.sax.*; 33 import org.xml.sax.helpers.AttributesImpl ; 34 35 import org.apache.axis.message.MessageElement; 36 import org.apache.axis.message.SOAPHeader; 37 import org.apache.axis.message.Text; 38 39 41 public class SOAPDataEncoder implements ContentHandler { 42 43 44 private static Logger mLogger = Logger.getLogger(SOAPDataEncoder.class); 45 46 47 private int initsize = 0; 48 private static final int DEFAULT_BUFFER_SIZE = 4096; 49 50 53 private FlashOutput mSWF = null; 54 57 private long mSize = -1; 58 59 private int mSWFVersion; 60 61 64 public SOAPDataEncoder (int swfversion) { 65 mSWFVersion = swfversion; 66 } 67 68 71 boolean isProgram = false; 72 73 77 public SOAPDataEncoder (int swfversion, int initsize) { 78 this(swfversion); 79 this.initsize = initsize; 80 } 81 82 public SOAPDataEncoder(int swfversion, Vector v, SOAPHeader h) { 83 this(swfversion); 84 buildFromElements(v, h); 85 } 86 87 public SOAPDataEncoder(int swfversion, Program p, SOAPHeader h) { 88 this(swfversion); 89 buildFromProgram(p, h); 90 } 91 92 public SOAPDataEncoder buildFromFault(AxisFault fault) { 93 start(); 94 String actor = fault.getFaultActor(); QName code = fault.getFaultCode(); String node = fault.getFaultNode(); String reason = fault.getFaultReason(); String role = fault.getFaultRole(); String faultstring = fault.getFaultString(); QName [] subcodes = fault.getFaultSubCodes(); 104 int count = 0; 105 if (subcodes != null) { 106 for (int i=0; i < subcodes.length; i++) { 107 LZSOAPUtils.pushQName(program, subcodes[i], dc); 108 } 109 program.push(subcodes.length); 110 body.writeByte(Actions.InitArray); 111 count++; 112 } 113 if (actor != null) { 114 program.push("actor"); 115 program.push(actor); 116 count++; 117 } 118 if (node != null) { 119 program.push("node"); 120 program.push(node); 121 count++; 122 } 123 if (reason != null) { 124 program.push("reason"); 125 program.push(reason); 126 count++; 127 } 128 if (role != null) { 129 program.push("role"); 130 program.push(role); 131 count++; 132 } 133 if (faultstring != null) { 134 program.push("faultstring"); 135 program.push(faultstring); 136 count++; 137 } 138 if (code != null) { 139 program.push("code"); 140 LZSOAPUtils.pushQName(program, code, dc); 141 count++; 142 } 143 144 program.push("errortype"); 145 program.push("fault"); 146 147 program.push(count+1); 148 body.writeByte(Actions.InitObject); 149 end(); 150 151 return this; 152 } 153 154 public SOAPDataEncoder buildFromException(Exception e) { 155 start(); 156 { 157 Throwable cause = e.getCause(); 158 String message = e.getMessage(); 159 StringWriter sw = new StringWriter(); 160 e.printStackTrace(new PrintWriter(sw)); 161 162 int count = 3; 163 program.push("stacktrace"); 164 program.push(sw.toString()); 165 166 program.push("faultString"); 167 if (message != null) { 168 program.push(message); 169 } else { 170 program.push(sw.toString()); 171 } 172 173 if (cause != null) { 174 program.push("cause"); 175 program.push(cause.toString()); 176 count++; 177 } 178 179 program.push("errortype"); 180 program.push("exception"); 181 182 program.push(count); 183 184 body.writeByte(Actions.InitObject); 185 } 186 end(); 187 return this; 188 } 189 190 194 203 public void characters(char[] ch, int start, int length) { 204 String text = new String (ch, start, length); 205 characters(text); 206 } 207 208 215 public void characters(String text) { 216 body.writeByte(Actions.PushDuplicate); 220 222 223 body.writeByte(Actions.PushData); 224 int push_bufferpos = body.getPos(); 227 body.writeWord(0); 229 DataCommon.pushMergedStringData(text, body, dc); 230 body.writeByte(0x07); body.writeDWord(2); body.writeByte(0x08); body.writeByte(textnode_idx); 237 int total_size = body.getPos() - (push_bufferpos + 2); 239 body.writeWordAt(total_size, push_bufferpos); 241 242 body.writeByte(Actions.CallFunction); 243 body.writeByte(Actions.Pop); 245 } 246 247 248 261 public void endElement(String uri, String localName, String qName) { 262 body.writeByte(Actions.Pop); 264 } 265 266 271 public void endElement() { 272 body.writeByte(Actions.Pop); 274 } 275 276 277 282 public void endPrefixMapping(String prefix) { 283 } 284 285 293 public void ignorableWhitespace(char[] ch, int start, int length) { 294 } 295 296 305 public void processingInstruction(String target, String data) { 306 } 307 308 315 public void setDocumentLocator(Locator locator) { 316 } 317 318 325 public void skippedEntity(String name) { 326 } 327 328 329 DataContext dc; 330 private byte constructor_idx; 332 private byte textnode_idx; 333 334 FlashBuffer body; 335 Program program; 336 Program resultProgram; 337 FlashBuffer out; 338 339 public void start() { 340 body = new FlashBuffer(initsize == 0 ? DEFAULT_BUFFER_SIZE : initsize); 343 program = new Program(body); 344 dc = new DataContext(); 345 } 346 347 public void end() { 348 FlashBuffer body = program.body(); 349 350 program.push("_parent"); 352 program.getVar(); 353 program.push(3); program.push("_parent"); 355 program.getVar(); 356 program.push("loader"); 357 body.writeByte(Actions.GetMember); 358 program.push("returnData"); 359 program.callMethod(); 360 program.pop(); 361 362 byte pooldata[] = DataCommon.makeStringPool(dc); 364 final int MISC = 64; 366 out = new FlashBuffer(body.getSize() + pooldata.length + MISC); 367 out.writeByte( Actions.ConstantPool ); 369 out.writeWord( pooldata.length + 2 ); out.writeWord( dc.cpool.size() ); out.writeArray( pooldata, 0, pooldata.length); out.writeArray(body.getBuf(), 0, body.getSize()); 374 resultProgram = new Program(out); 375 } 376 377 382 public void startDocument() { 383 start(); 384 constructor_idx = (byte) (DataCommon.addStringConstant(DataCommon.NODE_INSTANTIATOR_FN, dc) & 0xFF); 385 textnode_idx = (byte) (DataCommon.addStringConstant(DataCommon.TEXT_INSTANTIATOR_FN, dc) & 0xFF); 386 387 program.push(new Object []{"_m", "_root"}); 390 program.getVar(); 391 program.push("_m"); 392 body.writeByte(Actions.GetMember); 393 program.setVar(); 394 395 program.push(new Object []{"_t", "_root"}); 397 program.getVar(); 398 program.push("_t"); 399 body.writeByte(Actions.GetMember); 400 program.setVar(); 401 } 402 403 408 public void endDocument() { 409 end(); 410 } 411 412 415 private Program getProgram() { 416 return resultProgram; 417 } 418 419 420 425 private FlashFile makeSWFFile() { 426 FlashFile file = FlashFile.newFlashFile(); 428 Script s = new Script(1); 429 file.setMainScript(s); 430 file.setVersion(mSWFVersion); 431 Frame frame = s.newFrame(); 432 frame.addFlashObject(new DoAction(resultProgram)); 433 return file; 434 } 435 436 437 445 public InputStream getInputStream() 446 throws IOException { 447 448 generate(); 449 return mSWF.getInputStream(); 450 } 451 452 459 public long getSize() 460 throws IOException { 461 462 generate(); 463 return mSize; 464 } 465 466 469 private void generate() throws IOException { 470 471 if (mSWF == null) { 472 try { 473 InputStream input; 474 FlashFile file = makeSWFFile(); 475 mSWF = file.generate(); 476 mSize = mSWF.pos; 477 } catch (IVException ex) { 478 throw new ChainedException(ex); 479 } 480 } 481 } 482 483 488 public void _startElement (String localName) { 489 490 } 491 492 496 public void addAttribute (String attrName, String attrVal) { 497 498 } 499 500 501 518 public void startElement(String uri, String localName, String qName, Attributes atts) { 519 startElement(localName, atts); 520 } 521 522 523 534 public void startElement(String localName, Attributes atts) { 535 int idx; body.writeByte(Actions.PushDuplicate); 540 541 body.writeByte(Actions.PushData); 547 int push_bufferpos = body.getPos(); 550 body.writeWord(0); 552 String eltname = localName; 554 DataCommon.pushMergedStringDataSymbol(eltname, body, dc); 555 556 int nattrs = atts.getLength(); 559 560 for (int i = 0; i < nattrs; i++) { 562 String attrname = atts.getLocalName(i); 563 DataCommon.pushMergedStringDataSymbol(attrname, body, dc); 565 566 String attrval = atts.getValue(i); 567 DataCommon.pushMergedStringData(attrval, body, dc); 569 } 570 body.writeByte(0x07); body.writeDWord(nattrs); 573 int total_size = body.getPos() - (push_bufferpos + 2); 575 body.writeWordAt(total_size, push_bufferpos); 577 body.writeByte(Actions.InitObject); 578 579 body.writeByte(Actions.PushData); 584 body.writeWord(7); 585 body.writeByte(0x07); body.writeDWord(3); body.writeByte(0x08); body.writeByte(constructor_idx); body.writeByte(Actions.CallFunction); 590 } 593 594 601 public void startPrefixMapping(String prefix, String uri) { 602 } 603 604 605 609 private void buildHeaders(SOAPHeader h) { 610 int hCount = 0; 611 Iterator iter = h.getChildElements(); 612 while (iter.hasNext()) { 613 hCount++; 614 traverseDOM((SOAPElement )iter.next()); 615 } 616 if (hCount != 0) { 617 program.push(hCount); 618 body.writeByte(Actions.InitArray); 619 } else { 620 LZSOAPUtils.pushNull(body); 621 } 622 } 623 624 629 public void buildFromElements(Vector v, SOAPHeader h) { 630 startDocument(); 631 632 buildHeaders(h); 634 635 for (int i = v.size()-1; i >= 0; --i) { 637 traverseDOM((SOAPElement )v.get(i)); 638 } 639 program.push(v.size()); 640 body.writeByte(Actions.InitArray); 641 642 endDocument(); 643 } 644 645 646 651 public void buildFromProgram(Program p, SOAPHeader h) { 652 isProgram = true; 654 655 startDocument(); 656 657 buildHeaders(h); 659 660 if ( p == null ) { 662 LZSOAPUtils.pushNull(body); 663 } else { 664 body.writeFOB(p.body()); 665 } 666 667 endDocument(); 668 } 669 670 671 674 private void traverseDOM(SOAPElement el) { 675 program.push(0); program.push("_root"); 680 program.getVar(); 681 program.push(DataCommon.ROOT_NODE_INSTANTIATOR_FN); 682 program.callMethod(); 683 686 AttributesImpl emptyAttr = new AttributesImpl (); 687 690 _traverseDOM(el); 692 693 696 program.push(1); 699 program.push("_root"); 700 program.getVar(); 701 program.push(DataCommon.ROOT_NODE_FINAL_FN); 702 program.callMethod(); 703 } 704 705 706 709 private void _traverseDOM(SOAPElement el) { 710 AttributesImpl attrs = new AttributesImpl (); 711 Iterator iter = el.getAllAttributes(); 712 while (iter.hasNext()) { 713 Name attrName = (Name )iter.next(); 714 String attrValue = el.getAttributeValue(attrName); 715 attrs.addAttribute(attrName.getURI(), attrName.getLocalName(), 716 attrName.getQualifiedName(), "", 717 attrValue); 718 } 719 720 Name elName = el.getElementName(); 721 startElement(elName.getLocalName(), attrs); 722 723 iter = el.getChildElements(); 724 while (iter.hasNext()) { 725 Object o = iter.next(); 726 if (Text.class.isInstance(o)) { 727 characters(((Text)o).getValue()); 729 } else { 730 SOAPElement child = (SOAPElement )o; 731 _traverseDOM(child); 732 } 733 } 734 735 736 endElement(); 737 738 } 739 740 741 } 742 | Popular Tags |