001// $ANTLR 2.7.7 (20060906): "distinguishedName.g" -> "AntlrDnParser.java"$ 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * https://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 * 021 */ 022package org.apache.directory.api.ldap.model.name; 023 024import java.io.StringReader; 025import java.util.ArrayList; 026import java.util.HashMap; 027import java.util.List; 028import java.util.Map; 029 030import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException; 031import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException; 032import javax.naming.NameParser; 033import org.apache.directory.api.ldap.model.entry.Value; 034import org.apache.directory.api.ldap.model.schema.SchemaManager; 035import org.apache.directory.api.ldap.model.schema.AttributeType; 036import org.apache.directory.api.util.ExpansibleByteBuffer; 037import org.apache.directory.api.util.Strings; 038import org.apache.directory.api.util.Unicode; 039 040import antlr.TokenBuffer; 041import antlr.TokenStreamException; 042import antlr.TokenStreamIOException; 043import antlr.ANTLRException; 044import antlr.LLkParser; 045import antlr.Token; 046import antlr.TokenStream; 047import antlr.RecognitionException; 048import antlr.NoViableAltException; 049import antlr.MismatchedTokenException; 050import antlr.SemanticException; 051import antlr.ParserSharedInputState; 052import antlr.collections.impl.BitSet; 053 054/** 055 * An antlr generated Dn parser. 056 * 057 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 058 */ 059public class AntlrDnParser extends antlr.LLkParser implements AntlrDnTokenTypes 060 { 061 062 private void matchedProduction( String msg ) 063 { 064 } 065 066 /** 067 * This class is used to store the decoded value 068 */ 069 private static class UpAndNormValue 070 { 071 // The value as a byte array 072 ExpansibleByteBuffer bytes = new ExpansibleByteBuffer(); 073 074 // The user provided value 075 StringBuilder upValue = new StringBuilder(); 076 077 // The normalized value 078 StringBuilder normValue = new StringBuilder(); 079 080 // A flag set to false if we have a binary value 081 boolean isHR = true; 082 } 083 084 085 private String createNormAva( Ava ava ) 086 { 087 StringBuilder rdnNormStr = new StringBuilder(); 088 Value value = ava.getValue(); 089 AttributeType attributeType = ava.getAttributeType(); 090 rdnNormStr.append( ava.getNormType() ); 091 rdnNormStr.append( '=' ); 092 093 if ( value != null ) 094 { 095 if ( value.getNormalized() != null ) 096 { 097 rdnNormStr.append( value.getNormalized() ); 098 } 099 else 100 { 101 // We can't tell if the value is HR or not. 102 // Use the Value User Provided value 103 rdnNormStr.append( value.getUpValue() ); 104 } 105 } 106 107 return rdnNormStr.toString(); 108 } 109 110protected AntlrDnParser(TokenBuffer tokenBuf, int k) { 111 super(tokenBuf,k); 112 tokenNames = _tokenNames; 113} 114 115public AntlrDnParser(TokenBuffer tokenBuf) { 116 this(tokenBuf,3); 117} 118 119protected AntlrDnParser(TokenStream lexer, int k) { 120 super(lexer,k); 121 tokenNames = _tokenNames; 122} 123 124public AntlrDnParser(TokenStream lexer) { 125 this(lexer,3); 126} 127 128public AntlrDnParser(ParserSharedInputState state) { 129 super(state,3); 130 tokenNames = _tokenNames; 131} 132 133/** 134 * Parses a Dn string. 135 * 136 * RFC 4514, Section 3 137 * <pre> 138 * distinguishedName = [ relativeDistinguishedName 139 * *( COMMA relativeDistinguishedName ) ] 140 * </pre> 141 * 142 * RFC 2253, Section 3 143 * <pre> 144 * distinguishedName = [name] 145 * name = name-component *("," name-component) 146 * </pre> 147 * 148 * RFC 1779, Section 2.3 149 * <pre> 150 * <name> ::= <name-component> ( <spaced-separator> ) 151 * | <name-component> <spaced-separator> <name> 152 * <spaced-separator> ::= <optional-space> 153 * <separator> 154 * <optional-space> 155 * <separator> ::= "," | ";" 156 * <optional-space> ::= ( <CR> ) *( " " ) 157 * </pre> 158 * 159 * @param schemaManager The SchemaManager 160 * @param dn The Dn to update 161 * @throws RecognitionException If the token is invalid 162 * @throws TokenStreamException When we weren't able to fetch a token 163 */ 164 public final void distinguishedName( 165 SchemaManager schemaManager, Dn dn 166 ) throws RecognitionException, TokenStreamException { 167 168 169 matchedProduction( "distinguishedName()" ); 170 Rdn rdn = new Rdn( schemaManager ); 171 172 173 { 174 switch ( LA(1)) { 175 case SPACE: 176 case NUMERICOID: 177 case ALPHA: 178 { 179 relativeDistinguishedName(schemaManager, rdn); 180 181 try 182 { 183 dn.add( rdn ); 184 185 } 186 catch ( LdapInvalidDnException lide ) 187 { 188 // Do nothing, can't get an exception here 189 } 190 191 { 192 _loop53: 193 do { 194 if ((LA(1)==COMMA||LA(1)==SEMI)) { 195 { 196 switch ( LA(1)) { 197 case COMMA: 198 { 199 match(COMMA); 200 break; 201 } 202 case SEMI: 203 { 204 match(SEMI); 205 break; 206 } 207 default: 208 { 209 throw new NoViableAltException(LT(1), getFilename()); 210 } 211 } 212 } 213 214 rdn = new Rdn( schemaManager ); 215 216 relativeDistinguishedName(schemaManager, rdn); 217 218 try 219 { 220 dn.add( rdn ); 221 } 222 catch ( LdapInvalidDnException lide ) 223 { 224 // Do nothing, can't get an exception here 225 } 226 227 } 228 else { 229 break _loop53; 230 } 231 232 } while (true); 233 } 234 match(Token.EOF_TYPE); 235 break; 236 } 237 case EOF: 238 { 239 break; 240 } 241 default: 242 { 243 throw new NoViableAltException(LT(1), getFilename()); 244 } 245 } 246 } 247 } 248 249/** 250 * Parses a Rdn string. 251 * 252 * RFC 4514, Section 3 253 * <pre> 254 * relativeDistinguishedName = attributeTypeAndValue 255 * *( PLUS attributeTypeAndValue ) 256 * </pre> 257 * 258 * RFC 2253, Section 3 259 * <pre> 260 * name-component = attributeTypeAndValue *("+" attributeTypeAndValue) 261 * </pre> 262 * 263 * RFC 1779, Section 2.3 264 * <pre> 265 * <name-component> ::= <attribute> 266 * | <attribute> <optional-space> "+" 267 * <optional-space> <name-component> 268 * </pre> 269 * 270 * @param schemaManager The SchemaManager 271 * @param rdn The Rdn to update 272 * @throws RecognitionException If the token is invalid 273 * @throws TokenStreamException When we weren't able to fetch a token 274 */ 275 public final void relativeDistinguishedName( 276 SchemaManager schemaManager, Rdn rdn 277 ) throws RecognitionException, TokenStreamException { 278 279 280 matchedProduction( "relativeDistinguishedName()" ); 281 String tmp; 282 283 // The rdnStr variable is used to gather the full RDN string 284 // as provided 285 StringBuilder rdnUpStr = new StringBuilder(); 286 StringBuilder rdnNormStr = new StringBuilder(); 287 int avaPos = 0; 288 AttributeType attributeType; 289 Value val; 290 Ava ava = new Ava( schemaManager); 291 String upAva; 292 293 // The list of parsed Ava for a later post-processing 294 List<Ava> avas = new ArrayList<>(); 295 296 297 { 298 upAva=attributeTypeAndValue(schemaManager, ava); 299 300 ava.hashCode(); 301 rdnUpStr.append( upAva ); 302 avas.add( ava ); 303 304 { 305 _loop62: 306 do { 307 if ((LA(1)==PLUS)) { 308 match(PLUS); 309 310 ava = new Ava( schemaManager); 311 312 upAva=attributeTypeAndValue(schemaManager, ava); 313 314 ava.hashCode(); 315 rdnUpStr.append( '+' ).append( upAva ); 316 317 try 318 { 319 Rdn.addOrdered( avas, ava ); 320 } 321 catch ( LdapInvalidDnException lide ) 322 { 323 throw new SemanticException( lide.getMessage() ); 324 } 325 326 } 327 else { 328 break _loop62; 329 } 330 331 } while (true); 332 } 333 } 334 335 // Now, build the Rdn 336 switch ( avas.size() ) 337 { 338 case 0: 339 // Can't be... 340 case 1: 341 // One single Ava 342 rdn.upName = rdnUpStr.toString(); 343 rdn.normName = createNormAva( ava ); 344 rdn.ava = ava; 345 rdn.avaType = ava.getType(); 346 rdn.nbAvas = 1; 347 break; 348 349 default: 350 rdn.nbAvas = avas.size(); 351 rdn.avaTypes = new HashMap<String, List<Ava>>(); 352 boolean isFirst = true; 353 354 for ( Ava parsedAva : avas ) 355 { 356 if ( isFirst ) 357 { 358 isFirst = false; 359 } 360 else 361 { 362 rdnNormStr.append( '+' ); 363 } 364 365 String type; 366 367 if ( schemaManager != null ) 368 { 369 type = parsedAva.getAttributeType().getOid(); 370 rdnNormStr.append( type ); 371 } 372 else 373 { 374 type = parsedAva.normType; 375 rdnNormStr.append( type ); 376 } 377 378 rdnNormStr.append( '=' ); 379 380 val = parsedAva.getValue(); 381 382 if ( ( val != null ) && ( val.getNormalized() != null ) ) 383 { 384 rdnNormStr.append( val.getNormalized() ); 385 } 386 else 387 { 388 rdnNormStr.append( val.getUpValue() ); 389 } 390 391 List<Ava> avaList = rdn.avaTypes.get( type ); 392 393 if ( avaList == null ) 394 { 395 avaList = new ArrayList<>(); 396 } 397 398 avaList.add( parsedAva ); 399 rdn.avaTypes.put( type, avaList ); 400 } 401 402 rdn.upName = rdnUpStr.toString(); 403 rdn.normName = rdnNormStr.toString(); 404 rdn.avas = avas; 405 406 break; 407 } 408 409 rdn.hashCode(); 410 411 } 412 413/** 414 * Parses a Dn string. 415 * 416 * RFC 4514, Section 3 417 * <pre> 418 * distinguishedName = [ relativeDistinguishedName 419 * *( COMMA relativeDistinguishedName ) ] 420 * </pre> 421 * 422 * RFC 2253, Section 3 423 * <pre> 424 * distinguishedName = [name] 425 * name = name-component *("," name-component) 426 * </pre> 427 * 428 * RFC 1779, Section 2.3 429 * <pre> 430 * <name> ::= <name-component> ( <spaced-separator> ) 431 * | <name-component> <spaced-separator> <name> 432 * <spaced-separator> ::= <optional-space> 433 * <separator> 434 * <optional-space> 435 * <separator> ::= "," | ";" 436 * <optional-space> ::= ( <CR> ) *( " " ) 437 * </pre> 438 * 439 * @param schemaManager The SchemaManager 440 * @param rdns The list of Rdns to update 441 * @return The normalized Dn 442 * @throws RecognitionException If the token is invalid 443 * @throws TokenStreamException When we weren't able to fetch a token 444 */ 445 public final String relativeDistinguishedNames( 446 SchemaManager schemaManager, List<Rdn> rdns 447 ) throws RecognitionException, TokenStreamException { 448 String normNameStr; 449 450 451 matchedProduction( "relativeDistinguishedNames()" ); 452 Rdn rdn = new Rdn( schemaManager ); 453 StringBuilder dnNormSb = new StringBuilder(); 454 455 456 { 457 switch ( LA(1)) { 458 case SPACE: 459 case NUMERICOID: 460 case ALPHA: 461 { 462 relativeDistinguishedName( schemaManager, rdn); 463 464 rdns.add( rdn ); 465 dnNormSb.append( rdn.getNormName() ); 466 rdn = new Rdn( schemaManager ); 467 468 { 469 _loop58: 470 do { 471 if ((LA(1)==COMMA||LA(1)==SEMI)) { 472 { 473 switch ( LA(1)) { 474 case COMMA: 475 { 476 match(COMMA); 477 break; 478 } 479 case SEMI: 480 { 481 match(SEMI); 482 break; 483 } 484 default: 485 { 486 throw new NoViableAltException(LT(1), getFilename()); 487 } 488 } 489 } 490 relativeDistinguishedName(schemaManager, rdn); 491 492 rdns.add( rdn ); 493 dnNormSb.append( ',' ); 494 dnNormSb.append( rdn.getNormName() ); 495 rdn = new Rdn( schemaManager ); 496 497 } 498 else { 499 break _loop58; 500 } 501 502 } while (true); 503 } 504 match(Token.EOF_TYPE); 505 break; 506 } 507 case EOF: 508 { 509 break; 510 } 511 default: 512 { 513 throw new NoViableAltException(LT(1), getFilename()); 514 } 515 } 516 } 517 518 normNameStr = dnNormSb.toString(); 519 520 return normNameStr; 521 } 522 523/** 524 * RFC 4514, Section 3 525 * <pre> 526 * attributeTypeAndValue = attributeType EQUALS attributeValue 527 * </pre> 528 * 529 * RFC 2253, Section 3 530 * <pre> 531 * attributeTypeAndValue = attributeType "=" attributeValue 532 * </pre> 533 * 534 * @param schemaManager The SchemaManager 535 * @param ava The parsed Ava 536 * @return The user provided Ava 537 * @throws RecognitionException If the token is invalid 538 * @throws TokenStreamException When we weren't able to fetch a token 539 */ 540 public final String attributeTypeAndValue( 541 SchemaManager schemaManager, Ava ava 542 ) throws RecognitionException, TokenStreamException { 543 String upNameStr; 544 545 546 matchedProduction( "attributeTypeAndValue()" ); 547 String type = null; 548 UpAndNormValue value = new UpAndNormValue(); 549 StringBuilder rdnUpName = new StringBuilder(); 550 551 552 { 553 { 554 _loop66: 555 do { 556 if ((LA(1)==SPACE)) { 557 match(SPACE); 558 rdnUpName.append( ' ' ); 559 } 560 else { 561 break _loop66; 562 } 563 564 } while (true); 565 } 566 type=attributeType(); 567 rdnUpName.append( type ); 568 { 569 _loop68: 570 do { 571 if ((LA(1)==SPACE)) { 572 match(SPACE); 573 rdnUpName.append( ' ' ); 574 } 575 else { 576 break _loop68; 577 } 578 579 } while (true); 580 } 581 match(EQUALS); 582 rdnUpName.append( '=' ); 583 { 584 _loop70: 585 do { 586 if ((LA(1)==SPACE) && (_tokenSet_0.member(LA(2))) && (_tokenSet_1.member(LA(3)))) { 587 match(SPACE); 588 rdnUpName.append( ' ' ); 589 } 590 else { 591 break _loop70; 592 } 593 594 } while (true); 595 } 596 attributeValue(value); 597 598 try 599 { 600 // We have to remove the ending spaces that may have been added, as the tutf1 rule 601 // cannot be processed 602 rdnUpName.append( value.upValue ); 603 AttributeType attributeType = null; 604 605 if ( schemaManager != null ) 606 { 607 if ( ( type.startsWith( "oid." ) ) || ( type.startsWith( "OID." ) ) ) 608 { 609 type = type.substring( 4 ); 610 } 611 612 attributeType = schemaManager.getAttributeType( type ); 613 ava.attributeType = attributeType; 614 ava.upType = type; 615 ava.normType = attributeType.getOid(); 616 } 617 else 618 { 619 ava.upType = type; 620 ava.normType = Strings.lowerCaseAscii( Strings.trim( type ) ); 621 } 622 623 if ( ( ( attributeType != null ) && attributeType.isHR() ) || value.isHR ) 624 { 625 int valueLength = value.upValue.length(); 626 int pos = value.bytes.position(); 627 628 for ( int i = valueLength - 1; i >= 0; i-- ) 629 { 630 if ( value.upValue.charAt( i ) == ' ' ) 631 { 632 if ( i == 0 ) 633 { 634 // The value is empty 635 ava = new Ava( schemaManager, type, rdnUpName.toString(), ( String ) null ); 636 break; 637 } 638 else if ( value.upValue.charAt( i - 1 ) != '\\' ) 639 { 640 // This is a trailing space, get rid of it 641 value.upValue.deleteCharAt( i ); 642 pos--; 643 value.bytes.position( pos ); 644 } 645 else 646 { 647 // This is an escaped space, get out 648 break; 649 } 650 } 651 else 652 { 653 break; 654 } 655 } 656 657 if ( attributeType != null ) 658 { 659 try 660 { 661 if ( ava == null ) 662 { 663 ava.upName = rdnUpName.toString(); 664 ava.value = new Value( attributeType, Strings.utf8ToString( value.bytes.copyOfUsedBytes() ) ); 665 } 666 else 667 { 668 ava.upName = rdnUpName.toString(); 669 ava.value = new Value( attributeType, Strings.utf8ToString( value.bytes.copyOfUsedBytes() ) ); 670 } 671 } 672 catch ( LdapInvalidAttributeValueException liave ) 673 { 674 throw new SemanticException( liave.getMessage() ); 675 } 676 } 677 else 678 { 679 if ( ava == null ) 680 { 681 ava.upName = rdnUpName.toString(); 682 ava.value = new Value( Strings.utf8ToString( value.bytes.copyOfUsedBytes() ) ); 683 } 684 else 685 { 686 ava.upName = rdnUpName.toString(); 687 ava.value = new Value( Strings.utf8ToString( value.bytes.copyOfUsedBytes() ) ); 688 } 689 } 690 } 691 else 692 { 693 ava.upName = rdnUpName.toString(); 694 ava.value = new Value( value.bytes.copyOfUsedBytes() ); 695 } 696 } 697 catch ( LdapInvalidDnException e ) 698 { 699 throw new SemanticException( e.getMessage() ); 700 } 701 702 { 703 _loop72: 704 do { 705 if ((LA(1)==SPACE)) { 706 match(SPACE); 707 rdnUpName.append( ' ' ); 708 } 709 else { 710 break _loop72; 711 } 712 713 } while (true); 714 } 715 } 716 717 upNameStr = rdnUpName.toString(); 718 719 return upNameStr; 720 } 721 722/** 723 * RFC 4514 Section 3 724 * 725 * <pre> 726 * attributeType = descr / numericoid 727 * </pre> 728 * 729 * @return The AttributeType 730 * @throws RecognitionException If the token is invalid 731 * @throws TokenStreamException When we weren't able to fetch a token 732 */ 733 public final String attributeType() throws RecognitionException, TokenStreamException { 734 String attributeType; 735 736 737 matchedProduction( "attributeType()" ); 738 739 740 { 741 switch ( LA(1)) { 742 case ALPHA: 743 { 744 attributeType=descr(); 745 break; 746 } 747 case NUMERICOID: 748 { 749 attributeType=numericoid(); 750 break; 751 } 752 default: 753 { 754 throw new NoViableAltException(LT(1), getFilename()); 755 } 756 } 757 } 758 return attributeType; 759 } 760 761/** 762 * RFC 4514, Section 3 763 * <pre> 764 * attributeValue = string / hexstring 765 * </pre> 766 * 767 * RFC 2253, Section 3 768 * <pre> 769 * attributeValue = string 770 * string = *( stringchar / pair ) 771 * / "#" hexstring 772 * / QUOTATION *( quotechar / pair ) QUOTATION ; only from v2 773 * 774 * We still accept both forms, which means we can have a value surrounded by '"' 775 * </pre> 776 * 777 * @param value The value to update 778 * @throws RecognitionException If the token is invalid 779 * @throws TokenStreamException When we weren't able to fetch a token 780 */ 781 public final void attributeValue( 782 UpAndNormValue value 783 ) throws RecognitionException, TokenStreamException { 784 785 786 matchedProduction( "attributeValue()" ); 787 788 789 { 790 switch ( LA(1)) { 791 case DQUOTE: 792 { 793 quotestring(value); 794 break; 795 } 796 case EQUALS: 797 case HYPHEN: 798 case UNDERSCORE: 799 case NUMERICOID: 800 case DIGIT: 801 case ALPHA: 802 case HEXPAIR: 803 case ESC: 804 case ESCESC: 805 case ESCSHARP: 806 case UTFMB: 807 case CHAR_REST: 808 { 809 string(value); 810 break; 811 } 812 case HEXVALUE: 813 { 814 hexstring(value); 815 break; 816 } 817 case EOF: 818 case COMMA: 819 case PLUS: 820 case SEMI: 821 case SPACE: 822 { 823 break; 824 } 825 default: 826 { 827 throw new NoViableAltException(LT(1), getFilename()); 828 } 829 } 830 } 831 } 832 833/** 834 * RFC 4512 Section 1.4 835 * 836 * <pre> 837 * descr = keystring 838 * keystring = leadkeychar *keychar 839 * leadkeychar = ALPHA 840 * keychar = ALPHA / DIGIT / HYPHEN 841 * </pre> 842 * 843 * We additionally add UNDERSCORE because some servers allow them. 844 * 845 * @return The description 846 * @throws RecognitionException If the token is invalid 847 * @throws TokenStreamException When we weren't able to fetch a token 848 */ 849 public final String descr() throws RecognitionException, TokenStreamException { 850 String descr; 851 852 Token leadkeychar = null; 853 Token alpha = null; 854 Token digit = null; 855 856 matchedProduction( "descr()" ); 857 StringBuilder descrSb = new StringBuilder(); 858 859 860 leadkeychar = LT(1); 861 match(ALPHA); 862 descrSb.append( leadkeychar.getText() ); 863 { 864 _loop77: 865 do { 866 switch ( LA(1)) { 867 case ALPHA: 868 { 869 alpha = LT(1); 870 match(ALPHA); 871 descrSb.append( alpha.getText() ); 872 break; 873 } 874 case DIGIT: 875 { 876 digit = LT(1); 877 match(DIGIT); 878 descrSb.append( digit.getText() ); 879 break; 880 } 881 case HYPHEN: 882 { 883 match(HYPHEN); 884 descrSb.append( '-' ); 885 break; 886 } 887 case UNDERSCORE: 888 { 889 match(UNDERSCORE); 890 descrSb.append( '_' ); 891 break; 892 } 893 default: 894 { 895 break _loop77; 896 } 897 } 898 } while (true); 899 } 900 901 descr = descrSb.toString(); 902 903 return descr; 904 } 905 906/** 907 * RFC 4512 Section 1.4 908 * 909 * <pre> 910 * numericoid = number 1*( DOT number ) 911 * number = DIGIT / ( LDIGIT 1*DIGIT ) 912 * DIGIT = %x30 / LDIGIT ; "0"-"9" 913 * LDIGIT = %x31-39 ; "1"-"9" 914 * </pre> 915 * 916 * @return The numeric OID 917 * @throws RecognitionException If the token is invalid 918 * @throws TokenStreamException When we weren't able to fetch a token 919 */ 920 public final String numericoid() throws RecognitionException, TokenStreamException { 921 String numericoid = ""; 922 923 Token noid = null; 924 925 matchedProduction( "numericoid()" ); 926 927 928 noid = LT(1); 929 match(NUMERICOID); 930 numericoid = noid.getText(); 931 return numericoid; 932 } 933 934/** 935 * RFC 2253, Section 3 936 * <pre> 937 * / QUOTATION *( quotechar / pair ) QUOTATION ; only from v2 938 * quotechar = <any character except "\" or QUOTATION > 939 * </pre> 940 * 941 * @param value The value to update 942 * @throws RecognitionException If the token is invalid 943 * @throws TokenStreamException When we weren't able to fetch a token 944 */ 945 public final void quotestring( 946 UpAndNormValue value 947 ) throws RecognitionException, TokenStreamException { 948 949 Token s = null; 950 951 matchedProduction( "quotestring()" ); 952 953 954 { 955 match(DQUOTE); 956 value.upValue.append( '"' ); 957 { 958 _loop86: 959 do { 960 switch ( LA(1)) { 961 case COMMA: 962 case EQUALS: 963 case PLUS: 964 case HYPHEN: 965 case UNDERSCORE: 966 case SEMI: 967 case LANGLE: 968 case RANGLE: 969 case SPACE: 970 case NUMERICOID_OR_ALPHA_OR_DIGIT: 971 case NUMERICOID: 972 case DOT: 973 case NUMBER: 974 case LDIGIT: 975 case DIGIT: 976 case ALPHA: 977 case HEXPAIR_OR_ESCESC_ESCSHARP_OR_ESC: 978 case HEX: 979 case HEXVALUE_OR_SHARP: 980 case HEXVALUE: 981 case SHARP: 982 case UTFMB: 983 case CHAR_REST: 984 { 985 { 986 { 987 s = LT(1); 988 match(_tokenSet_2); 989 } 990 991 value.upValue.append( s.getText() ); 992 value.bytes.append( Strings.getBytesUtf8( s.getText() ) ); 993 994 } 995 break; 996 } 997 case HEXPAIR: 998 case ESC: 999 case ESCESC: 1000 case ESCSHARP: 1001 { 1002 pair(value); 1003 break; 1004 } 1005 default: 1006 { 1007 break _loop86; 1008 } 1009 } 1010 } while (true); 1011 } 1012 match(DQUOTE); 1013 value.upValue.append( '"' ); 1014 } 1015 } 1016 1017/** 1018 * RFC 4514 Section 3 1019 * 1020 * <pre> 1021 * ; The following characters are to be escaped when they appear 1022 * ; in the value to be encoded: ESC, one of <escaped>, <leading> 1023 * ; SHARP or SPACE, trailing SPACE, and NULL. 1024 * string = [ ( leadchar / pair ) [ *( stringchar / pair ) ( trailchar / pair ) ] ] 1025 * leadchar = LUTF1 | UTFMB 1026 * stringchar = SUTF1 / UTFMB 1027 * trailchar = TUTF1 / UTFMB 1028 * </pre> 1029 * 1030 * @param value The value to update 1031 * @throws RecognitionException If the token is invalid 1032 * @throws TokenStreamException When we weren't able to fetch a token 1033 */ 1034 public final void string( 1035 UpAndNormValue value 1036 ) throws RecognitionException, TokenStreamException { 1037 1038 1039 matchedProduction( "string()" ); 1040 1041 1042 { 1043 { 1044 switch ( LA(1)) { 1045 case EQUALS: 1046 case HYPHEN: 1047 case UNDERSCORE: 1048 case NUMERICOID: 1049 case DIGIT: 1050 case ALPHA: 1051 case CHAR_REST: 1052 { 1053 lutf1(value); 1054 break; 1055 } 1056 case UTFMB: 1057 { 1058 utfmb(value); 1059 break; 1060 } 1061 case HEXPAIR: 1062 case ESC: 1063 case ESCESC: 1064 case ESCSHARP: 1065 { 1066 pair(value); 1067 break; 1068 } 1069 default: 1070 { 1071 throw new NoViableAltException(LT(1), getFilename()); 1072 } 1073 } 1074 } 1075 { 1076 _loop92: 1077 do { 1078 switch ( LA(1)) { 1079 case UTFMB: 1080 { 1081 utfmb(value); 1082 break; 1083 } 1084 case HEXPAIR: 1085 case ESC: 1086 case ESCESC: 1087 case ESCSHARP: 1088 { 1089 pair(value); 1090 break; 1091 } 1092 default: 1093 if ((_tokenSet_3.member(LA(1))) && (_tokenSet_4.member(LA(2))) && (_tokenSet_5.member(LA(3)))) { 1094 sutf1(value); 1095 } 1096 else { 1097 break _loop92; 1098 } 1099 } 1100 } while (true); 1101 } 1102 } 1103 } 1104 1105/** 1106 * RFC 4514 Section 3 1107 * 1108 * <pre> 1109 * hexstring = SHARP 1*hexpair 1110 * 1111 * If in <hexstring> form, a BER representation can be obtained from 1112 * converting each <hexpair> of the <hexstring> to the octet indicated 1113 * by the <hexpair>. 1114 * </pre> 1115 * 1116 * @param value The value to update 1117 * @throws RecognitionException If the token is invalid 1118 * @throws TokenStreamException When we weren't able to fetch a token 1119 */ 1120 public final void hexstring( 1121 UpAndNormValue value 1122 ) throws RecognitionException, TokenStreamException { 1123 1124 Token hexValue = null; 1125 1126 matchedProduction( "hexstring()" ); 1127 1128 1129 hexValue = LT(1); 1130 match(HEXVALUE); 1131 1132 String hexStr = hexValue.getText(); 1133 value.upValue.append( '#' ).append( hexStr ); 1134 value.bytes.append( Strings.toByteArray( hexStr ) ); 1135 value.isHR = false; 1136 1137 } 1138 1139/** 1140 * RFC 4514, Section 3 1141 * <pre> 1142 * pair = ESC ( ESC / special / hexpair ) 1143 * special = escaped / SPACE / SHARP / EQUALS 1144 * escaped = DQUOTE / PLUS / COMMA / SEMI / LANGLE / RANGLE 1145 * hexpair = HEX HEX 1146 * 1147 * If in <string> form, a LDAP string representation asserted value can 1148 * be obtained by replacing (left to right, non-recursively) each <pair> 1149 * appearing in the <string> as follows: 1150 * replace <ESC><ESC> with <ESC>; 1151 * replace <ESC><special> with <special>; 1152 * replace <ESC><hexpair> with the octet indicated by the <hexpair>. 1153 * </pre> 1154 * 1155 * RFC 2253, Section 3 1156 * <pre> 1157 * pair = "\" ( special / "\" / QUOTATION / hexpair ) 1158 * special = "," / "=" / "+" / "<" / ">" / "#" / ";" 1159 * </pre> 1160 * 1161 * RFC 1779, Section 2.3 1162 * <pre> 1163 * <pair> ::= "\" ( <special> | "\" | '"') 1164 * <special> ::= "," | "=" | <CR> | "+" | "<" | ">" 1165 * | "#" | ";" 1166 * </pre> 1167 * 1168 * @param value The value to update 1169 * @throws RecognitionException If the token is invalid 1170 * @throws TokenStreamException When we weren't able to fetch a token 1171 */ 1172 public final void pair( 1173 UpAndNormValue value 1174 ) throws RecognitionException, TokenStreamException { 1175 1176 Token hexpair = null; 1177 1178 matchedProduction( "pair()" ); 1179 char specialChar; 1180 1181 1182 switch ( LA(1)) { 1183 case ESCESC: 1184 { 1185 { 1186 match(ESCESC); 1187 1188 value.upValue.append( "\\\\" ); 1189 value.bytes.append( '\\' ); 1190 1191 } 1192 break; 1193 } 1194 case ESCSHARP: 1195 { 1196 { 1197 match(ESCSHARP); 1198 1199 value.upValue.append( "\\#" ); 1200 value.bytes.append( '#' ); 1201 1202 } 1203 break; 1204 } 1205 case ESC: 1206 { 1207 { 1208 match(ESC); 1209 specialChar=special(); 1210 1211 value.upValue.append( '\\' ).append( specialChar ); 1212 value.bytes.append( specialChar ); 1213 1214 } 1215 break; 1216 } 1217 case HEXPAIR: 1218 { 1219 { 1220 hexpair = LT(1); 1221 match(HEXPAIR); 1222 1223 value.upValue.append( '\\' ).append( hexpair.getText() ); 1224 value.bytes.append( Strings.toByteArray( hexpair.getText() ) ); 1225 1226 } 1227 break; 1228 } 1229 default: 1230 { 1231 throw new NoViableAltException(LT(1), getFilename()); 1232 } 1233 } 1234 } 1235 1236/** 1237 * RFC 4514, Section 3: 1238 * <pre> 1239 * LUTF1 = %x01-1F / %x21 / %x24-2A / %x2D-3A / 1240 * %x3D / %x3F-5B / %x5D-7F 1241 * 1242 * The rule CHAR_REST doesn't contain the following charcters, 1243 * so we must check them additionally 1244 * EQUALS (0x3D) 1245 * HYPHEN (0x2D) 1246 * UNDERSCORE (0x5F) 1247 * DIGIT (0x30-0x39) 1248 * ALPHA (0x41-0x5A and 0x61-0x7A) 1249 * </pre> 1250 * 1251 * @param value The value to update 1252 * @throws RecognitionException If the token is invalid 1253 * @throws TokenStreamException When we weren't able to fetch a token 1254 */ 1255 public final void lutf1( 1256 UpAndNormValue value 1257 ) throws RecognitionException, TokenStreamException { 1258 1259 Token rest = null; 1260 Token digit = null; 1261 Token alpha = null; 1262 Token numericoid = null; 1263 1264 matchedProduction( "lutf1()" ); 1265 1266 1267 switch ( LA(1)) { 1268 case CHAR_REST: 1269 { 1270 rest = LT(1); 1271 match(CHAR_REST); 1272 1273 char c = rest.getText().charAt( 0 ); 1274 value.upValue.append( c ); 1275 value.bytes.append( ( byte ) c ); 1276 1277 break; 1278 } 1279 case EQUALS: 1280 { 1281 match(EQUALS); 1282 1283 value.upValue.append( '=' ); 1284 value.bytes.append( '=' ); 1285 1286 break; 1287 } 1288 case HYPHEN: 1289 { 1290 match(HYPHEN); 1291 1292 value.upValue.append( '-' ); 1293 value.bytes.append( '-' ); 1294 1295 break; 1296 } 1297 case UNDERSCORE: 1298 { 1299 match(UNDERSCORE); 1300 1301 value.upValue.append( '_' ); 1302 value.bytes.append( '_' ); 1303 1304 break; 1305 } 1306 case DIGIT: 1307 { 1308 digit = LT(1); 1309 match(DIGIT); 1310 1311 char c = digit.getText().charAt( 0 ); 1312 value.upValue.append( c ); 1313 value.bytes.append( ( byte ) c ); 1314 1315 break; 1316 } 1317 case ALPHA: 1318 { 1319 alpha = LT(1); 1320 match(ALPHA); 1321 1322 char c = alpha.getText().charAt( 0 ); 1323 value.upValue.append( c ); 1324 value.bytes.append( ( byte ) c ); 1325 1326 break; 1327 } 1328 case NUMERICOID: 1329 { 1330 numericoid = LT(1); 1331 match(NUMERICOID); 1332 1333 String number = numericoid.getText(); 1334 value.upValue.append( number ); 1335 value.bytes.append( Strings.getBytesUtf8( number ) ); 1336 1337 break; 1338 } 1339 default: 1340 { 1341 throw new NoViableAltException(LT(1), getFilename()); 1342 } 1343 } 1344 } 1345 1346/** 1347 * Process a UTFMB char 1348 * 1349 * @param value The value to update 1350 * @throws RecognitionException If the token is invalid 1351 * @throws TokenStreamException When we weren't able to fetch a token 1352 */ 1353 public final void utfmb( 1354 UpAndNormValue value 1355 ) throws RecognitionException, TokenStreamException { 1356 1357 Token s = null; 1358 1359 matchedProduction( "utfmb()" ); 1360 1361 1362 s = LT(1); 1363 match(UTFMB); 1364 1365 char c = s.getText().charAt( 0 ); 1366 value.upValue.append( c ); 1367 value.bytes.append( Unicode.charToBytes( c ) ); 1368 1369 } 1370 1371/** 1372 * RFC 4514, Section 3: 1373 * <pre> 1374 * SUTF1 = %x01-21 / %x23-2A / %x2D-3A / 1375 * %x3D / %x3F-5B / %x5D-7F 1376 * 1377 * The rule CHAR_REST doesn't contain the following charcters, 1378 * so we must check them additionally 1379 * EQUALS (0x3D) 1380 * HYPHEN (0x2D) 1381 * UNDERSCORE (0x5F) 1382 * DIGIT (0x30-0x39) 1383 * ALPHA (0x41-0x5A and 0x61-0x7A) 1384 * SHARP (0x23) 1385 * SPACE (0x20) 1386 * </pre> 1387 * 1388 * @param value The value to update 1389 * @throws RecognitionException If the token is invalid 1390 * @throws TokenStreamException When we weren't able to fetch a token 1391 */ 1392 public final void sutf1( 1393 UpAndNormValue value 1394 ) throws RecognitionException, TokenStreamException { 1395 1396 Token rest = null; 1397 Token digit = null; 1398 Token alpha = null; 1399 Token hex = null; 1400 Token numericoid = null; 1401 1402 matchedProduction( "sutf1()" ); 1403 1404 1405 switch ( LA(1)) { 1406 case CHAR_REST: 1407 { 1408 rest = LT(1); 1409 match(CHAR_REST); 1410 1411 char c = rest.getText().charAt( 0 ); 1412 value.upValue.append( c ); 1413 value.bytes.append( ( byte ) c ); 1414 1415 break; 1416 } 1417 case EQUALS: 1418 { 1419 match(EQUALS); 1420 1421 value.upValue.append( '=' ); 1422 value.bytes.append( '=' ); 1423 1424 break; 1425 } 1426 case HYPHEN: 1427 { 1428 match(HYPHEN); 1429 1430 value.upValue.append( '-' ); 1431 value.bytes.append( '-' ); 1432 1433 break; 1434 } 1435 case UNDERSCORE: 1436 { 1437 match(UNDERSCORE); 1438 1439 value.upValue.append( '_' ); 1440 value.bytes.append( '_' ); 1441 1442 break; 1443 } 1444 case DIGIT: 1445 { 1446 digit = LT(1); 1447 match(DIGIT); 1448 1449 char c = digit.getText().charAt( 0 ); 1450 value.upValue.append( c ); 1451 value.bytes.append( ( byte ) c ); 1452 1453 break; 1454 } 1455 case ALPHA: 1456 { 1457 alpha = LT(1); 1458 match(ALPHA); 1459 1460 char c = alpha.getText().charAt( 0 ); 1461 value.upValue.append( c ); 1462 value.bytes.append( ( byte ) c ); 1463 1464 break; 1465 } 1466 case SHARP: 1467 { 1468 match(SHARP); 1469 1470 value.upValue.append( '#' ); 1471 value.bytes.append( '#' ); 1472 1473 break; 1474 } 1475 case SPACE: 1476 { 1477 match(SPACE); 1478 1479 value.upValue.append( ' ' ); 1480 value.bytes.append( ' ' ); 1481 1482 break; 1483 } 1484 case HEXVALUE: 1485 { 1486 hex = LT(1); 1487 match(HEXVALUE); 1488 1489 String hexStr = hex.getText(); 1490 value.upValue.append( '#' ).append( hexStr ); 1491 value.bytes.append( '#' ); 1492 value.bytes.append( Strings.getBytesUtf8( hexStr ) ); 1493 1494 break; 1495 } 1496 case NUMERICOID: 1497 { 1498 numericoid = LT(1); 1499 match(NUMERICOID); 1500 1501 String number = numericoid.getText(); 1502 value.upValue.append( number ); 1503 value.bytes.append( Strings.getBytesUtf8( number ) ); 1504 1505 break; 1506 } 1507 default: 1508 { 1509 throw new NoViableAltException(LT(1), getFilename()); 1510 } 1511 } 1512 } 1513 1514/** 1515 * RFC 4514 Section 3 1516 * 1517 * <pre> 1518 * special = escaped / SPACE / SHARP / EQUALS 1519 * escaped = DQUOTE / PLUS / COMMA / SEMI / LANGLE / RANGLE 1520 * </pre> 1521 * 1522 * @return The special char 1523 * @throws RecognitionException If the token is invalid 1524 * @throws TokenStreamException When we weren't able to fetch a token 1525 */ 1526 public final char special() throws RecognitionException, TokenStreamException { 1527 char special; 1528 1529 1530 matchedProduction( "()" ); 1531 1532 1533 { 1534 switch ( LA(1)) { 1535 case DQUOTE: 1536 { 1537 match(DQUOTE); 1538 special = '"'; 1539 break; 1540 } 1541 case PLUS: 1542 { 1543 match(PLUS); 1544 special = '+'; 1545 break; 1546 } 1547 case COMMA: 1548 { 1549 match(COMMA); 1550 special = ','; 1551 break; 1552 } 1553 case SEMI: 1554 { 1555 match(SEMI); 1556 special = ';'; 1557 break; 1558 } 1559 case LANGLE: 1560 { 1561 match(LANGLE); 1562 special = '<'; 1563 break; 1564 } 1565 case RANGLE: 1566 { 1567 match(RANGLE); 1568 special = '>'; 1569 break; 1570 } 1571 case SPACE: 1572 { 1573 match(SPACE); 1574 special = ' '; 1575 break; 1576 } 1577 case SHARP: 1578 { 1579 match(SHARP); 1580 special = '#'; 1581 break; 1582 } 1583 case EQUALS: 1584 { 1585 match(EQUALS); 1586 special = '='; 1587 break; 1588 } 1589 default: 1590 { 1591 throw new NoViableAltException(LT(1), getFilename()); 1592 } 1593 } 1594 } 1595 return special; 1596 } 1597 1598 1599 public static final String[] _tokenNames = { 1600 "<0>", 1601 "EOF", 1602 "<2>", 1603 "NULL_TREE_LOOKAHEAD", 1604 "COMMA", 1605 "EQUALS", 1606 "PLUS", 1607 "HYPHEN", 1608 "UNDERSCORE", 1609 "DQUOTE", 1610 "SEMI", 1611 "LANGLE", 1612 "RANGLE", 1613 "SPACE", 1614 "NUMERICOID_OR_ALPHA_OR_DIGIT", 1615 "NUMERICOID", 1616 "DOT", 1617 "NUMBER", 1618 "LDIGIT", 1619 "DIGIT", 1620 "ALPHA", 1621 "HEXPAIR_OR_ESCESC_ESCSHARP_OR_ESC", 1622 "HEXPAIR", 1623 "ESC", 1624 "ESCESC", 1625 "ESCSHARP", 1626 "HEX", 1627 "HEXVALUE_OR_SHARP", 1628 "HEXVALUE", 1629 "SHARP", 1630 "UTFMB", 1631 "CHAR_REST" 1632 }; 1633 1634 private static final long[] mk_tokenSet_0() { 1635 long[] data = { 3554191346L, 0L}; 1636 return data; 1637 } 1638 public static final BitSet _tokenSet_0 = new BitSet(mk_tokenSet_0()); 1639 private static final long[] mk_tokenSet_1() { 1640 long[] data = { 4294967282L, 0L, 0L, 0L}; 1641 return data; 1642 } 1643 public static final BitSet _tokenSet_1 = new BitSet(mk_tokenSet_1()); 1644 private static final long[] mk_tokenSet_2() { 1645 long[] data = { 4232052208L, 0L, 0L, 0L}; 1646 return data; 1647 } 1648 public static final BitSet _tokenSet_2 = new BitSet(mk_tokenSet_2()); 1649 private static final long[] mk_tokenSet_3() { 1650 long[] data = { 2954404256L, 0L}; 1651 return data; 1652 } 1653 public static final BitSet _tokenSet_3 = new BitSet(mk_tokenSet_3()); 1654 private static final long[] mk_tokenSet_4() { 1655 long[] data = { 4091061746L, 0L}; 1656 return data; 1657 } 1658 public static final BitSet _tokenSet_4 = new BitSet(mk_tokenSet_4()); 1659 private static final long[] mk_tokenSet_5() { 1660 long[] data = { 4091068402L, 0L}; 1661 return data; 1662 } 1663 public static final BitSet _tokenSet_5 = new BitSet(mk_tokenSet_5()); 1664 1665 }