URI.as
1 package com.adobe.net 2 { 3 public class URI 4 { 5 6 public static const EQUAL:int = 2; 7 8 public static const PARENT:int = 3; 9 10 public static const URImustEscape:String = " %"; 11 12 public static const URIqueryEscape:String = URImustEscape + "#"; 13 14 protected static const URIqueryExcludedBitmap:URIEncodingBitmap = new URIEncodingBitmap(URIqueryEscape); 15 16 public static const URIpathEscape:String = URImustEscape + "?#"; 17 18 protected static const URIfragmentExcludedBitmap:URIEncodingBitmap = URIqueryExcludedBitmap; 19 20 public static const UNKNOWN_SCHEME:String = "unknown"; 21 22 protected static var _resolver:IURIResolver = null; 23 24 public static const URIqueryPartEscape:String = URImustEscape + "#&="; 25 26 protected static const URIqueryPartExcludedBitmap:URIEncodingBitmap = new URIEncodingBitmap(URIqueryPartEscape); 27 28 protected static const URIpathExcludedBitmap:URIEncodingBitmap = new URIEncodingBitmap(URIpathEscape); 29 30 public static const URIbaselineEscape:String = URImustEscape + ":?#/@"; 31 32 protected static const URIbaselineExcludedBitmap:URIEncodingBitmap = new URIEncodingBitmap(URIbaselineEscape); 33 34 protected static const URIschemeExcludedBitmap:URIEncodingBitmap = URIbaselineExcludedBitmap; 35 36 protected static const URIuserpassExcludedBitmap:URIEncodingBitmap = URIbaselineExcludedBitmap; 37 38 protected static const URIportExludedBitmap:URIEncodingBitmap = URIbaselineExcludedBitmap; 39 40 protected static const URIauthorityExcludedBitmap:URIEncodingBitmap = URIbaselineExcludedBitmap; 41 42 public static const URInonHierEscape:String = URImustEscape + "?#/"; 43 44 protected static const URInonHierexcludedBitmap:URIEncodingBitmap = new URIEncodingBitmap(URInonHierEscape); 45 46 public static const CHILD:int = 1; 47 48 public static const NOT_RELATED:int = 0; 49 50 51 protected var _path:String = ""; 52 53 protected var _relative:Boolean = false; 54 55 protected var _fragment:String = ""; 56 57 protected var _username:String = ""; 58 59 protected var _nonHierarchical:String = ""; 60 61 protected var _authority:String = ""; 62 63 protected var _query:String = ""; 64 65 protected var _scheme:String = ""; 66 67 protected var _port:String = ""; 68 69 protected var _password:String = ""; 70 71 protected var _valid:Boolean = false; 72 73 public function URI(uri:String = null) 74 { 75 super(); 76 if(uri == null) 77 { 78 this.initialize(); 79 } 80 else 81 { 82 this.constructURI(uri); 83 } 84 } 85 86 public static function get resolver() : IURIResolver 87 { 88 return _resolver; 89 } 90 91 protected static function compareStr(str1:String, str2:String, sensitive:Boolean = true) : Boolean 92 { 93 if(sensitive == false) 94 { 95 str1 = str1.toLowerCase(); 96 str2 = str2.toLowerCase(); 97 } 98 return str1 == str2; 99 } 100 101 public static function set resolver(resolver:IURIResolver) : void 102 { 103 _resolver = resolver; 104 } 105 106 public static function unescapeChars(escaped:String) : String 107 { 108 var unescaped:String = null; 109 return decodeURIComponent(escaped); 110 } 111 112 public static function queryPartEscape(unescaped:String) : String 113 { 114 var escaped:String = unescaped; 115 return URI.fastEscapeChars(unescaped,URI.URIqueryPartExcludedBitmap); 116 } 117 118 public static function escapeChars(unescaped:String) : String 119 { 120 return fastEscapeChars(unescaped,URI.URIbaselineExcludedBitmap); 121 } 122 123 public static function fastEscapeChars(unescaped:String, bitmap:URIEncodingBitmap) : String 124 { 125 var c:String = null; 126 var x:int = 0; 127 var i:int = 0; 128 var escaped:String = ""; 129 for(i = 0; i < unescaped.length; i++) 130 { 131 c = unescaped.charAt(i); 132 x = bitmap.ShouldEscape(c); 133 if(Boolean(x)) 134 { 135 c = x.toString(16); 136 if(c.length == 1) 137 { 138 c = "0" + c; 139 } 140 c = "%" + c; 141 c = c.toUpperCase(); 142 } 143 escaped += c; 144 } 145 return escaped; 146 } 147 148 public static function queryPartUnescape(escaped:String) : String 149 { 150 var unescaped:String = escaped; 151 return unescapeChars(unescaped); 152 } 153 154 protected static function resolve(uri:URI) : URI 155 { 156 var copy:URI = new URI(); 157 copy.copyURI(uri); 158 if(_resolver != null) 159 { 160 return _resolver.resolve(copy); 161 } 162 return copy; 163 } 164 165 public function set queryRaw(queryStr:String) : void 166 { 167 this._query = queryStr; 168 } 169 170 public function get port() : String 171 { 172 return URI.unescapeChars(this._port); 173 } 174 175 public function set port(portStr:String) : void 176 { 177 this._port = URI.escapeChars(portStr); 178 this.hierState = true; 179 } 180 181 public function getCommonParent(uri:URI, caseSensitive:Boolean = true) : URI 182 { 183 var strBefore:String = null; 184 var strAfter:String = null; 185 var thisURI:URI = URI.resolve(this); 186 var thatURI:URI = URI.resolve(uri); 187 if(!thisURI.isAbsolute() || !thatURI.isAbsolute() || thisURI.isHierarchical() == false || thatURI.isHierarchical() == false) 188 { 189 return null; 190 } 191 var relation:int = thisURI.getRelation(thatURI); 192 if(relation == URI.NOT_RELATED) 193 { 194 return null; 195 } 196 thisURI.chdir("."); 197 thatURI.chdir("."); 198 do 199 { 200 relation = thisURI.getRelation(thatURI,caseSensitive); 201 if(relation == URI.EQUAL || relation == URI.PARENT) 202 { 203 break; 204 } 205 strBefore = thisURI.toString(); 206 thisURI.chdir(".."); 207 strAfter = thisURI.toString(); 208 } 209 while(strBefore != strAfter); 210 211 return thisURI; 212 } 213 214 public function get nonHierarchical() : String 215 { 216 return URI.unescapeChars(this._nonHierarchical); 217 } 218 219 protected function set hierState(state:Boolean) : void 220 { 221 if(state) 222 { 223 this._nonHierarchical = ""; 224 if(this._scheme == "" || this._scheme == UNKNOWN_SCHEME) 225 { 226 this._relative = true; 227 } 228 else 229 { 230 this._relative = false; 231 } 232 if(this._authority.length == 0 && this._path.length == 0) 233 { 234 this._valid = false; 235 } 236 else 237 { 238 this._valid = true; 239 } 240 } 241 else 242 { 243 this._authority = ""; 244 this._username = ""; 245 this._password = ""; 246 this._port = ""; 247 this._path = ""; 248 this._relative = false; 249 if(this._scheme == "" || this._scheme == UNKNOWN_SCHEME) 250 { 251 this._valid = false; 252 } 253 else 254 { 255 this._valid = true; 256 } 257 } 258 } 259 260 public function setQueryValue(name:String, value:String) : void 261 { 262 var map:Object = null; 263 map = this.getQueryByMap(); 264 map[name] = value; 265 this.setQueryByMap(map); 266 } 267 268 public function getFilename(minusExtension:Boolean = false) : String 269 { 270 var filename:String = null; 271 var index:int = 0; 272 if(this.isDirectory()) 273 { 274 return String(""); 275 } 276 var pathStr:String = this.path; 277 index = pathStr.lastIndexOf("/"); 278 if(index != -1) 279 { 280 filename = pathStr.substr(index + 1); 281 } 282 else 283 { 284 filename = pathStr; 285 } 286 if(minusExtension) 287 { 288 index = filename.lastIndexOf("."); 289 if(index != -1) 290 { 291 filename = filename.substr(0,index); 292 } 293 } 294 return filename; 295 } 296 297 public function set authority(authorityStr:String) : void 298 { 299 authorityStr = authorityStr.toLowerCase(); 300 this._authority = URI.fastEscapeChars(authorityStr,URI.URIauthorityExcludedBitmap); 301 this.hierState = true; 302 } 303 304 protected function initialize() : void 305 { 306 this._valid = false; 307 this._relative = false; 308 this._scheme = UNKNOWN_SCHEME; 309 this._authority = ""; 310 this._username = ""; 311 this._password = ""; 312 this._port = ""; 313 this._path = ""; 314 this._query = ""; 315 this._fragment = ""; 316 this._nonHierarchical = ""; 317 } 318 319 public function getQueryByMap() : Object 320 { 321 var queryStr:String = null; 322 var pair:String = null; 323 var pairs:Array = null; 324 var item:Array = null; 325 var name:String = null; 326 var value:String = null; 327 var map:Object = new Object(); 328 queryStr = this._query; 329 pairs = queryStr.split("&"); 330 for each(pair in pairs) 331 { 332 if(pair.length != 0) 333 { 334 item = pair.split("="); 335 if(item.length > 0) 336 { 337 name = String(item[0]); 338 if(item.length > 1) 339 { 340 value = String(item[1]); 341 } 342 else 343 { 344 value = ""; 345 } 346 name = queryPartUnescape(name); 347 value = queryPartUnescape(value); 348 map[name] = value; 349 } 350 } 351 } 352 return map; 353 } 354 355 protected function constructURI(uri:String) : Boolean 356 { 357 if(!this.parseURI(uri)) 358 { 359 this._valid = false; 360 } 361 return this.isValid(); 362 } 363 364 public function isRelative() : Boolean 365 { 366 return this._relative; 367 } 368 369 public function getExtension(minusDot:Boolean = false) : String 370 { 371 var extension:String = null; 372 var index:int = 0; 373 var filename:String = this.getFilename(); 374 if(filename == "") 375 { 376 return String(""); 377 } 378 index = filename.lastIndexOf("."); 379 if(index == -1 || index == 0) 380 { 381 return String(""); 382 } 383 extension = filename.substr(index); 384 if(minusDot && extension.charAt(0) == ".") 385 { 386 extension = extension.substr(1); 387 } 388 return extension; 389 } 390 391 public function get password() : String 392 { 393 return URI.unescapeChars(this._password); 394 } 395 396 public function setParts(schemeStr:String, authorityStr:String, portStr:String, pathStr:String, queryStr:String, fragmentStr:String) : void 397 { 398 this.scheme = schemeStr; 399 this.authority = authorityStr; 400 this.port = portStr; 401 this.path = pathStr; 402 this.query = queryStr; 403 this.fragment = fragmentStr; 404 this.hierState = true; 405 } 406 407 public function set query(queryStr:String) : void 408 { 409 this._query = URI.fastEscapeChars(queryStr,URI.URIqueryExcludedBitmap); 410 } 411 412 public function set fragment(fragmentStr:String) : void 413 { 414 this._fragment = URI.fastEscapeChars(fragmentStr,URIfragmentExcludedBitmap); 415 } 416 417 public function get path() : String 418 { 419 return URI.unescapeChars(this._path); 420 } 421 422 public function setQueryByMap(map:Object) : void 423 { 424 var item:String = null; 425 var name:String = null; 426 var value:String = null; 427 var tmpPair:String = null; 428 var queryStr:String = ""; 429 for(item in map) 430 { 431 name = item; 432 value = String(map[item]); 433 if(value == null) 434 { 435 value = ""; 436 } 437 name = queryPartEscape(name); 438 value = queryPartEscape(value); 439 tmpPair = name; 440 if(value.length > 0) 441 { 442 tmpPair += "="; 443 tmpPair += value; 444 } 445 if(queryStr.length != 0) 446 { 447 queryStr += "&"; 448 } 449 queryStr += tmpPair; 450 } 451 this._query = queryStr; 452 } 453 454 public function makeAbsoluteURI(base_uri:URI) : Boolean 455 { 456 if(this.isAbsolute() || base_uri.isRelative()) 457 { 458 return false; 459 } 460 var base:URI = new URI(); 461 base.copyURI(base_uri); 462 if(base.chdir(this.toString()) == false) 463 { 464 return false; 465 } 466 this.copyURI(base); 467 return true; 468 } 469 470 public function chdir(reference:String, escape:Boolean = false) : Boolean 471 { 472 var uriReference:URI = null; 473 var thisPath:String = null; 474 var thatPath:String = null; 475 var thisParts:Array = null; 476 var thatParts:Array = null; 477 var curDir:String = null; 478 var i:int = 0; 479 var f:String = null; 480 var ref:String = reference; 481 if(escape) 482 { 483 ref = URI.escapeChars(reference); 484 } 485 if(ref == "") 486 { 487 return true; 488 } 489 if(ref.substr(0,2) == "//") 490 { 491 f = this.scheme + ":" + ref; 492 return this.constructURI(f); 493 } 494 if(ref.charAt(0) == "?") 495 { 496 ref = "./" + ref; 497 } 498 uriReference = new URI(ref); 499 if(uriReference.isAbsolute() || uriReference.isHierarchical() == false) 500 { 501 this.copyURI(uriReference); 502 return true; 503 } 504 var thisIsDir:Boolean = false; 505 var thatIsDir:Boolean = false; 506 var thisIsAbs:Boolean = false; 507 var thatIsAbs:Boolean = false; 508 var lastIsDotOperation:Boolean = false; 509 thisPath = this.path; 510 thatPath = uriReference.path; 511 if(thisPath.length > 0) 512 { 513 thisParts = thisPath.split("/"); 514 } 515 else 516 { 517 thisParts = new Array(); 518 } 519 if(thatPath.length > 0) 520 { 521 thatParts = thatPath.split("/"); 522 } 523 else 524 { 525 thatParts = new Array(); 526 } 527 if(thisParts.length > 0 && thisParts[0] == "") 528 { 529 thisIsAbs = true; 530 thisParts.shift(); 531 } 532 if(thisParts.length > 0 && thisParts[thisParts.length - 1] == "") 533 { 534 thisIsDir = true; 535 thisParts.pop(); 536 } 537 if(thatParts.length > 0 && thatParts[0] == "") 538 { 539 thatIsAbs = true; 540 thatParts.shift(); 541 } 542 if(thatParts.length > 0 && thatParts[thatParts.length - 1] == "") 543 { 544 thatIsDir = true; 545 thatParts.pop(); 546 } 547 if(thatIsAbs) 548 { 549 this.path = uriReference.path; 550 this.queryRaw = uriReference.queryRaw; 551 this.fragment = uriReference.fragment; 552 return true; 553 } 554 if(thatParts.length == 0 && uriReference.query == "") 555 { 556 this.fragment = uriReference.fragment; 557 return true; 558 } 559 if(thisIsDir == false && thisParts.length > 0) 560 { 561 thisParts.pop(); 562 } 563 this.queryRaw = uriReference.queryRaw; 564 this.fragment = uriReference.fragment; 565 thisParts = thisParts.concat(thatParts); 566 for(i = 0; i < thisParts.length; i++) 567 { 568 curDir = String(thisParts[i]); 569 lastIsDotOperation = false; 570 if(curDir == ".") 571 { 572 thisParts.splice(i,1); 573 i -= 1; 574 lastIsDotOperation = true; 575 } 576 else if(curDir == "..") 577 { 578 if(i >= 1) 579 { 580 if(thisParts[i - 1] != "..") 581 { 582 thisParts.splice(i - 1,2); 583 i -= 2; 584 } 585 } 586 else if(!this.isRelative()) 587 { 588 thisParts.splice(i,1); 589 i -= 1; 590 } 591 lastIsDotOperation = true; 592 } 593 } 594 var finalPath:String = ""; 595 thatIsDir ||= lastIsDotOperation; 596 finalPath = this.joinPath(thisParts,thisIsAbs,thatIsDir); 597 this.path = finalPath; 598 return true; 599 } 600 601 public function get scheme() : String 602 { 603 return URI.unescapeChars(this._scheme); 604 } 605 606 public function makeRelativeURI(base_uri:URI, caseSensitive:Boolean = true) : Boolean 607 { 608 var thisParts:Array = null; 609 var thatParts:Array = null; 610 var thisPart:String = null; 611 var thatPart:String = null; 612 var finalPath:String = null; 613 var i:int = 0; 614 var base:URI = new URI(); 615 base.copyURI(base_uri); 616 var finalParts:Array = new Array(); 617 var pathStr:String = this.path; 618 var queryStr:String = this.queryRaw; 619 var fragmentStr:String = this.fragment; 620 var isDir:Boolean = false; 621 if(this.isRelative()) 622 { 623 return true; 624 } 625 if(base.isRelative()) 626 { 627 return false; 628 } 629 if(this.isOfType(base_uri.scheme) == false || this.authority != base_uri.authority) 630 { 631 return false; 632 } 633 isDir = this.isDirectory(); 634 base.chdir("."); 635 thisParts = pathStr.split("/"); 636 thatParts = base.path.split("/"); 637 if(thisParts.length > 0 && thisParts[0] == "") 638 { 639 thisParts.shift(); 640 } 641 if(thisParts.length > 0 && thisParts[thisParts.length - 1] == "") 642 { 643 isDir = true; 644 thisParts.pop(); 645 } 646 if(thatParts.length > 0 && thatParts[0] == "") 647 { 648 thatParts.shift(); 649 } 650 if(thatParts.length > 0 && thatParts[thatParts.length - 1] == "") 651 { 652 thatParts.pop(); 653 } 654 while(thatParts.length > 0) 655 { 656 if(thisParts.length == 0) 657 { 658 break; 659 } 660 thisPart = String(thisParts[0]); 661 thatPart = String(thatParts[0]); 662 if(!compareStr(thisPart,thatPart,caseSensitive)) 663 { 664 break; 665 } 666 thisParts.shift(); 667 thatParts.shift(); 668 } 669 for(i = 0; i < thatParts.length; i++) 670 { 671 finalParts.push(".."); 672 } 673 finalParts = finalParts.concat(thisParts); 674 finalPath = this.joinPath(finalParts,false,isDir); 675 if(finalPath.length == 0) 676 { 677 finalPath = "./"; 678 } 679 this.setParts("","","",finalPath,queryStr,fragmentStr); 680 return true; 681 } 682 683 public function set password(passwordStr:String) : void 684 { 685 this._password = URI.fastEscapeChars(passwordStr,URI.URIuserpassExcludedBitmap); 686 this.hierState = true; 687 } 688 689 public function toDisplayString() : String 690 { 691 return this.toStringInternal(true); 692 } 693 694 protected function parseURI(uri:String) : Boolean 695 { 696 var index:int = 0; 697 var index2:int = 0; 698 var baseURI:String = uri; 699 this.initialize(); 700 index = baseURI.indexOf("#"); 701 if(index != -1) 702 { 703 if(baseURI.length > index + 1) 704 { 705 this._fragment = baseURI.substr(index + 1,baseURI.length - (index + 1)); 706 } 707 baseURI = baseURI.substr(0,index); 708 } 709 index = baseURI.indexOf("?"); 710 if(index != -1) 711 { 712 if(baseURI.length > index + 1) 713 { 714 this._query = baseURI.substr(index + 1,baseURI.length - (index + 1)); 715 } 716 baseURI = baseURI.substr(0,index); 717 } 718 index = baseURI.search(":"); 719 index2 = baseURI.search("/"); 720 var containsColon:Boolean = index != -1; 721 var containsSlash:Boolean = index2 != -1; 722 var colonBeforeSlash:Boolean = !containsSlash || index < index2; 723 if(containsColon && colonBeforeSlash) 724 { 725 this._scheme = baseURI.substr(0,index); 726 this._scheme = this._scheme.toLowerCase(); 727 baseURI = baseURI.substr(index + 1); 728 if(baseURI.substr(0,2) != "//") 729 { 730 this._nonHierarchical = baseURI; 731 if((this._valid = this.validateURI()) == false) 732 { 733 this.initialize(); 734 } 735 return this.isValid(); 736 } 737 this._nonHierarchical = ""; 738 baseURI = baseURI.substr(2,baseURI.length - 2); 739 } 740 else 741 { 742 this._scheme = ""; 743 this._relative = true; 744 this._nonHierarchical = ""; 745 } 746 if(this.isRelative()) 747 { 748 this._authority = ""; 749 this._port = ""; 750 this._path = baseURI; 751 } 752 else 753 { 754 if(baseURI.substr(0,2) == "//") 755 { 756 while(baseURI.charAt(0) == "/") 757 { 758 baseURI = baseURI.substr(1,baseURI.length - 1); 759 } 760 } 761 index = baseURI.search("/"); 762 if(index == -1) 763 { 764 this._authority = baseURI; 765 this._path = ""; 766 } 767 else 768 { 769 this._authority = baseURI.substr(0,index); 770 this._path = baseURI.substr(index,baseURI.length - index); 771 } 772 index = this._authority.search("@"); 773 if(index != -1) 774 { 775 this._username = this._authority.substr(0,index); 776 this._authority = this._authority.substr(index + 1); 777 index = this._username.search(":"); 778 if(index != -1) 779 { 780 this._password = this._username.substring(index + 1,this._username.length); 781 this._username = this._username.substr(0,index); 782 } 783 else 784 { 785 this._password = ""; 786 } 787 } 788 else 789 { 790 this._username = ""; 791 this._password = ""; 792 } 793 index = this._authority.search(":"); 794 if(index != -1) 795 { 796 this._port = this._authority.substring(index + 1,this._authority.length); 797 this._authority = this._authority.substr(0,index); 798 } 799 else 800 { 801 this._port = ""; 802 } 803 this._authority = this._authority.toLowerCase(); 804 } 805 if((this._valid = this.validateURI()) == false) 806 { 807 this.initialize(); 808 } 809 return this.isValid(); 810 } 811 812 public function set username(usernameStr:String) : void 813 { 814 this._username = URI.fastEscapeChars(usernameStr,URI.URIuserpassExcludedBitmap); 815 this.hierState = true; 816 } 817 818 public function copyURI(uri:URI) : void 819 { 820 this._scheme = uri._scheme; 821 this._authority = uri._authority; 822 this._username = uri._username; 823 this._password = uri._password; 824 this._port = uri._port; 825 this._path = uri._path; 826 this._query = uri._query; 827 this._fragment = uri._fragment; 828 this._nonHierarchical = uri._nonHierarchical; 829 this._valid = uri._valid; 830 this._relative = uri._relative; 831 } 832 833 public function isAbsolute() : Boolean 834 { 835 return !this._relative; 836 } 837 838 protected function get hierState() : Boolean 839 { 840 return this._nonHierarchical.length == 0; 841 } 842 843 public function get queryRaw() : String 844 { 845 return this._query; 846 } 847 848 public function get query() : String 849 { 850 return URI.unescapeChars(this._query); 851 } 852 853 public function set scheme(schemeStr:String) : void 854 { 855 var normalized:String = schemeStr.toLowerCase(); 856 this._scheme = URI.fastEscapeChars(normalized,URI.URIschemeExcludedBitmap); 857 } 858 859 public function forceEscape() : void 860 { 861 this.scheme = this.scheme; 862 this.setQueryByMap(this.getQueryByMap()); 863 this.fragment = this.fragment; 864 if(this.isHierarchical()) 865 { 866 this.authority = this.authority; 867 this.path = this.path; 868 this.port = this.port; 869 this.username = this.username; 870 this.password = this.password; 871 } 872 else 873 { 874 this.nonHierarchical = this.nonHierarchical; 875 } 876 } 877 878 public function getDefaultPort() : String 879 { 880 if(this._scheme == "http") 881 { 882 return String("80"); 883 } 884 if(this._scheme == "ftp") 885 { 886 return String("21"); 887 } 888 if(this._scheme == "file") 889 { 890 return String(""); 891 } 892 if(this._scheme == "sftp") 893 { 894 return String("22"); 895 } 896 return String(""); 897 } 898 899 public function get fragment() : String 900 { 901 return URI.unescapeChars(this._fragment); 902 } 903 904 public function set path(pathStr:String) : void 905 { 906 this._path = URI.fastEscapeChars(pathStr,URI.URIpathExcludedBitmap); 907 if(this._scheme == UNKNOWN_SCHEME) 908 { 909 this._scheme = ""; 910 } 911 this.hierState = true; 912 } 913 914 public function get authority() : String 915 { 916 return URI.unescapeChars(this._authority); 917 } 918 919 public function isHierarchical() : Boolean 920 { 921 return this.hierState; 922 } 923 924 protected function toStringInternal(forDisplay:Boolean) : String 925 { 926 var uri:String = ""; 927 var part:String = ""; 928 if(this.isHierarchical() == false) 929 { 930 uri += forDisplay ? this.scheme : this._scheme; 931 uri += ":"; 932 uri += forDisplay ? this.nonHierarchical : this._nonHierarchical; 933 } 934 else 935 { 936 if(this.isRelative() == false) 937 { 938 if(this._scheme.length != 0) 939 { 940 part = forDisplay ? this.scheme : this._scheme; 941 uri += part + ":"; 942 } 943 if(this._authority.length != 0 || this.isOfType("file")) 944 { 945 uri += "//"; 946 if(this._username.length != 0) 947 { 948 part = forDisplay ? this.username : this._username; 949 uri += part; 950 if(this._password.length != 0) 951 { 952 part = forDisplay ? this.password : this._password; 953 uri += ":" + part; 954 } 955 uri += "@"; 956 } 957 part = forDisplay ? this.authority : this._authority; 958 uri += part; 959 if(this.port.length != 0) 960 { 961 uri += ":" + this.port; 962 } 963 } 964 } 965 part = forDisplay ? this.path : this._path; 966 uri += part; 967 } 968 if(this._query.length != 0) 969 { 970 part = forDisplay ? this.query : this._query; 971 uri += "?" + part; 972 } 973 if(this.fragment.length != 0) 974 { 975 part = forDisplay ? this.fragment : this._fragment; 976 uri += "#" + part; 977 } 978 return uri; 979 } 980 981 public function get username() : String 982 { 983 return URI.unescapeChars(this._username); 984 } 985 986 public function unknownToURI(unknown:String, defaultScheme:String = "http") : Boolean 987 { 988 var temp:String = null; 989 var path:String = null; 990 if(unknown.length == 0) 991 { 992 this.initialize(); 993 return false; 994 } 995 unknown = unknown.replace(/\\/g,"/"); 996 if(unknown.length >= 2) 997 { 998 temp = unknown.substr(0,2); 999 if(temp == "//") 1000 { 1001 unknown = defaultScheme + ":" + unknown; 1002 } 1003 } 1004 if(unknown.length >= 3) 1005 { 1006 temp = unknown.substr(0,3); 1007 if(temp == "://") 1008 { 1009 unknown = defaultScheme + unknown; 1010 } 1011 } 1012 var uri:URI = new URI(unknown); 1013 if(uri.isHierarchical() == false) 1014 { 1015 if(uri.scheme == UNKNOWN_SCHEME) 1016 { 1017 this.initialize(); 1018 return false; 1019 } 1020 this.copyURI(uri); 1021 this.forceEscape(); 1022 return true; 1023 } 1024 if(uri.scheme != UNKNOWN_SCHEME && uri.scheme.length > 0) 1025 { 1026 if(uri.authority.length > 0 || uri.scheme == "file") 1027 { 1028 this.copyURI(uri); 1029 this.forceEscape(); 1030 return true; 1031 } 1032 if(uri.authority.length == 0 && uri.path.length == 0) 1033 { 1034 this.setParts(uri.scheme,"","","","",""); 1035 return false; 1036 } 1037 } 1038 else 1039 { 1040 path = uri.path; 1041 if(path == ".." || path == "." || path.length >= 3 && path.substr(0,3) == "../" || path.length >= 2 && path.substr(0,2) == "./") 1042 { 1043 this.copyURI(uri); 1044 this.forceEscape(); 1045 return true; 1046 } 1047 } 1048 uri = new URI(defaultScheme + "://" + unknown); 1049 if(uri.scheme.length > 0 && uri.authority.length > 0) 1050 { 1051 this.copyURI(uri); 1052 this.forceEscape(); 1053 return true; 1054 } 1055 this.initialize(); 1056 return false; 1057 } 1058 1059 public function isDirectory() : Boolean 1060 { 1061 if(this._path.length == 0) 1062 { 1063 return false; 1064 } 1065 return this._path.charAt(this.path.length - 1) == "/"; 1066 } 1067 1068 protected function verifyAlpha(str:String) : Boolean 1069 { 1070 var index:int = 0; 1071 var pattern:RegExp = /[^a-z]/; 1072 str = str.toLowerCase(); 1073 index = str.search(pattern); 1074 if(index == -1) 1075 { 1076 return true; 1077 } 1078 return false; 1079 } 1080 1081 public function isOfFileType(extension:String) : Boolean 1082 { 1083 var thisExtension:String = null; 1084 var index:int = 0; 1085 index = extension.lastIndexOf("."); 1086 if(index != -1) 1087 { 1088 extension = extension.substr(index + 1); 1089 } 1090 thisExtension = this.getExtension(true); 1091 if(thisExtension == "") 1092 { 1093 return false; 1094 } 1095 if(compareStr(thisExtension,extension,false) == 0) 1096 { 1097 return true; 1098 } 1099 return false; 1100 } 1101 1102 public function set nonHierarchical(nonHier:String) : void 1103 { 1104 this._nonHierarchical = URI.fastEscapeChars(nonHier,URInonHierexcludedBitmap); 1105 this.hierState = false; 1106 } 1107 1108 protected function joinPath(parts:Array, isAbs:Boolean, isDir:Boolean) : String 1109 { 1110 var i:int = 0; 1111 var pathStr:String = ""; 1112 for(i = 0; i < parts.length; i++) 1113 { 1114 if(pathStr.length > 0) 1115 { 1116 pathStr += "/"; 1117 } 1118 pathStr += parts[i]; 1119 } 1120 if(isDir && pathStr.length > 0) 1121 { 1122 pathStr += "/"; 1123 } 1124 if(isAbs) 1125 { 1126 pathStr = "/" + pathStr; 1127 } 1128 return pathStr; 1129 } 1130 1131 public function isValid() : Boolean 1132 { 1133 return this._valid; 1134 } 1135 1136 public function toString() : String 1137 { 1138 return ""; 1139 } 1140 1141 protected function validateURI() : Boolean 1142 { 1143 if(this.isAbsolute()) 1144 { 1145 if(this._scheme.length <= 1 || this._scheme == UNKNOWN_SCHEME) 1146 { 1147 return false; 1148 } 1149 if(this.verifyAlpha(this._scheme) == false) 1150 { 1151 return false; 1152 } 1153 } 1154 if(this.hierState) 1155 { 1156 if(this._path.search("\\") != -1) 1157 { 1158 return false; 1159 } 1160 if(this.isRelative() == false && this._scheme == UNKNOWN_SCHEME) 1161 { 1162 return false; 1163 } 1164 } 1165 else if(this._nonHierarchical.search("\\") != -1) 1166 { 1167 return false; 1168 } 1169 return true; 1170 } 1171 1172 public function getRelation(uri:URI, caseSensitive:Boolean = true) : int 1173 { 1174 var thisParts:Array = null; 1175 var thatParts:Array = null; 1176 var thisPart:String = null; 1177 var thatPart:String = null; 1178 var i:int = 0; 1179 var thisURI:URI = URI.resolve(this); 1180 var thatURI:URI = URI.resolve(uri); 1181 if(thisURI.isRelative() || thatURI.isRelative()) 1182 { 1183 return URI.NOT_RELATED; 1184 } 1185 if(thisURI.isHierarchical() == false || thatURI.isHierarchical() == false) 1186 { 1187 if(thisURI.isHierarchical() == false && thatURI.isHierarchical() == true || thisURI.isHierarchical() == true && thatURI.isHierarchical() == false) 1188 { 1189 return URI.NOT_RELATED; 1190 } 1191 if(thisURI.scheme != thatURI.scheme) 1192 { 1193 return URI.NOT_RELATED; 1194 } 1195 if(thisURI.nonHierarchical != thatURI.nonHierarchical) 1196 { 1197 return URI.NOT_RELATED; 1198 } 1199 return URI.EQUAL; 1200 } 1201 if(thisURI.scheme != thatURI.scheme) 1202 { 1203 return URI.NOT_RELATED; 1204 } 1205 if(thisURI.authority != thatURI.authority) 1206 { 1207 return URI.NOT_RELATED; 1208 } 1209 var thisPort:String = thisURI.port; 1210 var thatPort:String = thatURI.port; 1211 if(thisPort == "") 1212 { 1213 thisPort = thisURI.getDefaultPort(); 1214 } 1215 if(thatPort == "") 1216 { 1217 thatPort = thatURI.getDefaultPort(); 1218 } 1219 if(thisPort != thatPort) 1220 { 1221 return URI.NOT_RELATED; 1222 } 1223 if(compareStr(thisURI.path,thatURI.path,caseSensitive)) 1224 { 1225 return URI.EQUAL; 1226 } 1227 var thisPath:String = thisURI.path; 1228 var thatPath:String = thatURI.path; 1229 if((thisPath == "/" || thatPath == "/") && (thisPath == "" || thatPath == "")) 1230 { 1231 return URI.EQUAL; 1232 } 1233 thisParts = thisPath.split("/"); 1234 thatParts = thatPath.split("/"); 1235 if(thisParts.length > thatParts.length) 1236 { 1237 thatPart = String(thatParts[thatParts.length - 1]); 1238 if(thatPart.length > 0) 1239 { 1240 return URI.NOT_RELATED; 1241 } 1242 thatParts.pop(); 1243 for(i = 0; i < thatParts.length; i++) 1244 { 1245 thisPart = String(thisParts[i]); 1246 thatPart = String(thatParts[i]); 1247 if(compareStr(thisPart,thatPart,caseSensitive) == false) 1248 { 1249 return URI.NOT_RELATED; 1250 } 1251 } 1252 return URI.CHILD; 1253 } 1254 if(thisParts.length < thatParts.length) 1255 { 1256 thisPart = String(thisParts[thisParts.length - 1]); 1257 if(thisPart.length > 0) 1258 { 1259 return URI.NOT_RELATED; 1260 } 1261 thisParts.pop(); 1262 for(i = 0; i < thisParts.length; i++) 1263 { 1264 thisPart = String(thisParts[i]); 1265 thatPart = String(thatParts[i]); 1266 if(compareStr(thisPart,thatPart,caseSensitive) == false) 1267 { 1268 return URI.NOT_RELATED; 1269 } 1270 } 1271 return URI.PARENT; 1272 } 1273 return URI.NOT_RELATED; 1274 } 1275 1276 public function isOfType(scheme:String) : Boolean 1277 { 1278 scheme = scheme.toLowerCase(); 1279 return this._scheme == scheme; 1280 } 1281 1282 public function getQueryValue(name:String) : String 1283 { 1284 var map:Object = null; 1285 var item:String = null; 1286 var value:String = null; 1287 map = this.getQueryByMap(); 1288 for(item in map) 1289 { 1290 if(item == name) 1291 { 1292 return String(map[item]); 1293 } 1294 } 1295 return new String(""); 1296 } 1297 } 1298 }