1 7 8 package javax.print; 9 10 import java.io.Serializable ; 11 12 import java.util.AbstractMap ; 13 import java.util.AbstractSet ; 14 import java.util.Iterator ; 15 import java.util.Map ; 16 import java.util.NoSuchElementException ; 17 import java.util.Set ; 18 import java.util.Vector ; 19 20 65 class MimeType implements Serializable , Cloneable { 66 67 private static final long serialVersionUID = -2785720609362367683L; 68 69 82 private String [] myPieces; 83 84 87 private transient String myStringValue = null; 88 89 92 private transient ParameterMapEntrySet myEntrySet = null; 93 94 97 private transient ParameterMap myParameterMap = null; 98 99 102 private class ParameterMapEntry implements Map.Entry { 103 private int myIndex; 104 public ParameterMapEntry(int theIndex) { 105 myIndex = theIndex; 106 } 107 public Object getKey(){ 108 return myPieces[myIndex]; 109 } 110 public Object getValue(){ 111 return myPieces[myIndex+1]; 112 } 113 public Object setValue (Object value) { 114 throw new UnsupportedOperationException (); 115 } 116 public boolean equals(Object o) { 117 return (o != null && 118 o instanceof Map.Entry && 119 getKey().equals (((Map.Entry ) o).getKey()) && 120 getValue().equals(((Map.Entry ) o).getValue())); 121 } 122 public int hashCode() { 123 return getKey().hashCode() ^ getValue().hashCode(); 124 } 125 } 126 127 130 private class ParameterMapEntrySetIterator implements Iterator { 131 private int myIndex = 2; 132 public boolean hasNext() { 133 return myIndex < myPieces.length; 134 } 135 public Object next() { 136 if (hasNext()) { 137 ParameterMapEntry result = new ParameterMapEntry (myIndex); 138 myIndex += 2; 139 return result; 140 } else { 141 throw new NoSuchElementException (); 142 } 143 } 144 public void remove() { 145 throw new UnsupportedOperationException (); 146 } 147 } 148 149 152 private class ParameterMapEntrySet extends AbstractSet { 153 public Iterator iterator() { 154 return new ParameterMapEntrySetIterator(); 155 } 156 public int size() { 157 return (myPieces.length - 2) / 2; 158 } 159 } 160 161 164 private class ParameterMap extends AbstractMap { 165 public Set entrySet() { 166 if (myEntrySet == null) { 167 myEntrySet = new ParameterMapEntrySet(); 168 } 169 return myEntrySet; 170 } 171 } 172 173 185 public MimeType(String s) { 186 parse (s); 187 } 188 189 193 public String getMimeType() { 194 return getStringValue(); 195 } 196 197 200 public String getMediaType() { 201 return myPieces[0]; 202 } 203 204 207 public String getMediaSubtype() { 208 return myPieces[1]; 209 } 210 211 219 public Map getParameterMap() { 220 if (myParameterMap == null) { 221 myParameterMap = new ParameterMap(); 222 } 223 return myParameterMap; 224 } 225 226 232 public String toString() { 233 return getStringValue(); 234 } 235 236 239 public int hashCode() { 240 return getStringValue().hashCode(); 241 } 242 243 259 public boolean equals (Object obj) { 260 return(obj != null && 261 obj instanceof MimeType && 262 getStringValue().equals(((MimeType ) obj).getStringValue())); 263 } 264 265 268 private String getStringValue() { 269 if (myStringValue == null) { 270 StringBuffer result = new StringBuffer (); 271 result.append (myPieces[0]); 272 result.append ('/'); 273 result.append (myPieces[1]); 274 int n = myPieces.length; 275 for (int i = 2; i < n; i += 2) { 276 result.append(';'); 277 result.append(' '); 278 result.append(myPieces[i]); 279 result.append('='); 280 result.append(addQuotes (myPieces[i+1])); 281 } 282 myStringValue = result.toString(); 283 } 284 return myStringValue; 285 } 286 287 290 private static final int TOKEN_LEXEME = 0; 292 private static final int QUOTED_STRING_LEXEME = 1; 293 private static final int TSPECIAL_LEXEME = 2; 294 private static final int EOF_LEXEME = 3; 295 private static final int ILLEGAL_LEXEME = 4; 296 297 private static class LexicalAnalyzer { 299 protected String mySource; 300 protected int mySourceLength; 301 protected int myCurrentIndex; 302 protected int myLexemeType; 303 protected int myLexemeBeginIndex; 304 protected int myLexemeEndIndex; 305 306 public LexicalAnalyzer(String theSource) { 307 mySource = theSource; 308 mySourceLength = theSource.length(); 309 myCurrentIndex = 0; 310 nextLexeme(); 311 } 312 313 public int getLexemeType() { 314 return myLexemeType; 315 } 316 317 public String getLexeme() { 318 return(myLexemeBeginIndex >= mySourceLength ? 319 null : 320 mySource.substring(myLexemeBeginIndex, myLexemeEndIndex)); 321 } 322 323 public char getLexemeFirstCharacter() { 324 return(myLexemeBeginIndex >= mySourceLength ? 325 '\u0000' : 326 mySource.charAt(myLexemeBeginIndex)); 327 } 328 329 public void nextLexeme() { 330 int state = 0; 331 int commentLevel = 0; 332 char c; 333 while (state >= 0) { 334 switch (state) { 335 case 0: 337 if (myCurrentIndex >= mySourceLength) { 338 myLexemeType = EOF_LEXEME; 339 myLexemeBeginIndex = mySourceLength; 340 myLexemeEndIndex = mySourceLength; 341 state = -1; 342 } else if (Character.isWhitespace 343 (c = mySource.charAt (myCurrentIndex ++))) { 344 state = 0; 345 } else if (c == '\"') { 346 myLexemeType = QUOTED_STRING_LEXEME; 347 myLexemeBeginIndex = myCurrentIndex; 348 state = 1; 349 } else if (c == '(') { 350 ++ commentLevel; 351 state = 3; 352 } else if (c == '/' || c == ';' || c == '=' || 353 c == ')' || c == '<' || c == '>' || 354 c == '@' || c == ',' || c == ':' || 355 c == '\\' || c == '[' || c == ']' || 356 c == '?') { 357 myLexemeType = TSPECIAL_LEXEME; 358 myLexemeBeginIndex = myCurrentIndex - 1; 359 myLexemeEndIndex = myCurrentIndex; 360 state = -1; 361 } else { 362 myLexemeType = TOKEN_LEXEME; 363 myLexemeBeginIndex = myCurrentIndex - 1; 364 state = 5; 365 } 366 break; 367 case 1: 369 if (myCurrentIndex >= mySourceLength) { 370 myLexemeType = ILLEGAL_LEXEME; 371 myLexemeBeginIndex = mySourceLength; 372 myLexemeEndIndex = mySourceLength; 373 state = -1; 374 } else if ((c = mySource.charAt (myCurrentIndex ++)) == '\"') { 375 myLexemeEndIndex = myCurrentIndex - 1; 376 state = -1; 377 } else if (c == '\\') { 378 state = 2; 379 } else { 380 state = 1; 381 } 382 break; 383 case 2: 385 if (myCurrentIndex >= mySourceLength) { 386 myLexemeType = ILLEGAL_LEXEME; 387 myLexemeBeginIndex = mySourceLength; 388 myLexemeEndIndex = mySourceLength; 389 state = -1; 390 } else { 391 ++ myCurrentIndex; 392 state = 1; 393 } break; 394 case 3: if (myCurrentIndex >= mySourceLength) { 396 myLexemeType = ILLEGAL_LEXEME; 397 myLexemeBeginIndex = mySourceLength; 398 myLexemeEndIndex = mySourceLength; 399 state = -1; 400 } else if ((c = mySource.charAt (myCurrentIndex ++)) == '(') { 401 ++ commentLevel; 402 state = 3; 403 } else if (c == ')') { 404 -- commentLevel; 405 state = commentLevel == 0 ? 0 : 3; 406 } else if (c == '\\') { 407 state = 4; 408 } else { state = 3; 409 } 410 break; 411 case 4: 413 if (myCurrentIndex >= mySourceLength) { 414 myLexemeType = ILLEGAL_LEXEME; 415 myLexemeBeginIndex = mySourceLength; 416 myLexemeEndIndex = mySourceLength; 417 state = -1; 418 } else { 419 ++ myCurrentIndex; 420 state = 3; 421 } 422 break; 423 case 5: 425 if (myCurrentIndex >= mySourceLength) { 426 myLexemeEndIndex = myCurrentIndex; 427 state = -1; 428 } else if (Character.isWhitespace 429 (c = mySource.charAt (myCurrentIndex ++))) { 430 myLexemeEndIndex = myCurrentIndex - 1; 431 state = -1; 432 } else if (c == '\"' || c == '(' || c == '/' || 433 c == ';' || c == '=' || c == ')' || 434 c == '<' || c == '>' || c == '@' || 435 c == ',' || c == ':' || c == '\\' || 436 c == '[' || c == ']' || c == '?') { 437 -- myCurrentIndex; 438 myLexemeEndIndex = myCurrentIndex; 439 state = -1; 440 } else { 441 state = 5; 442 } 443 break; 444 } 445 } 446 447 } 448 449 } 450 451 459 private static String toUnicodeLowerCase(String s) { 460 int n = s.length(); 461 char[] result = new char [n]; 462 for (int i = 0; i < n; ++ i) { 463 result[i] = Character.toLowerCase (s.charAt (i)); 464 } 465 return new String (result); 466 } 467 468 471 private static String removeBackslashes(String s) { 472 int n = s.length(); 473 char[] result = new char [n]; 474 int i; 475 int j = 0; 476 char c; 477 for (i = 0; i < n; ++ i) { 478 c = s.charAt (i); 479 if (c == '\\') { 480 c = s.charAt (++ i); 481 } 482 result[j++] = c; 483 } 484 return new String (result, 0, j); 485 } 486 487 491 private static String addQuotes(String s) { 492 int n = s.length(); 493 int i; 494 char c; 495 StringBuffer result = new StringBuffer (n+2); 496 result.append ('\"'); 497 for (i = 0; i < n; ++ i) { 498 c = s.charAt (i); 499 if (c == '\"') { 500 result.append ('\\'); 501 } 502 result.append (c); 503 } 504 result.append ('\"'); 505 return result.toString(); 506 } 507 508 526 private void parse(String s) { 527 if (s == null) { 529 throw new NullPointerException (); 530 } 531 LexicalAnalyzer theLexer = new LexicalAnalyzer (s); 532 int theLexemeType; 533 Vector thePieces = new Vector (); 534 boolean mediaTypeIsText = false; 535 boolean parameterNameIsCharset = false; 536 537 if (theLexer.getLexemeType() == TOKEN_LEXEME) { 539 String mt = toUnicodeLowerCase (theLexer.getLexeme()); 540 thePieces.add (mt); 541 theLexer.nextLexeme(); 542 mediaTypeIsText = mt.equals ("text"); 543 } else { 544 throw new IllegalArgumentException (); 545 } 546 if (theLexer.getLexemeType() == TSPECIAL_LEXEME && 548 theLexer.getLexemeFirstCharacter() == '/') { 549 theLexer.nextLexeme(); 550 } else { 551 throw new IllegalArgumentException (); 552 } 553 if (theLexer.getLexemeType() == TOKEN_LEXEME) { 554 thePieces.add (toUnicodeLowerCase (theLexer.getLexeme())); 555 theLexer.nextLexeme(); 556 } else { 557 throw new IllegalArgumentException (); 558 } 559 while (theLexer.getLexemeType() == TSPECIAL_LEXEME && 561 theLexer.getLexemeFirstCharacter() == ';') { 562 theLexer.nextLexeme(); 564 565 if (theLexer.getLexemeType() == TOKEN_LEXEME) { 567 String pn = toUnicodeLowerCase (theLexer.getLexeme()); 568 thePieces.add (pn); 569 theLexer.nextLexeme(); 570 parameterNameIsCharset = pn.equals ("charset"); 571 } else { 572 throw new IllegalArgumentException (); 573 } 574 575 if (theLexer.getLexemeType() == TSPECIAL_LEXEME && 577 theLexer.getLexemeFirstCharacter() == '=') { 578 theLexer.nextLexeme(); 579 } else { 580 throw new IllegalArgumentException (); 581 } 582 583 if (theLexer.getLexemeType() == TOKEN_LEXEME) { 585 String pv = theLexer.getLexeme(); 586 thePieces.add(mediaTypeIsText && parameterNameIsCharset ? 587 toUnicodeLowerCase (pv) : 588 pv); 589 theLexer.nextLexeme(); 590 } else if (theLexer.getLexemeType() == QUOTED_STRING_LEXEME) { 591 String pv = removeBackslashes (theLexer.getLexeme()); 592 thePieces.add(mediaTypeIsText && parameterNameIsCharset ? 593 toUnicodeLowerCase (pv) : 594 pv); 595 theLexer.nextLexeme(); 596 } else { 597 throw new IllegalArgumentException (); 598 } 599 } 600 601 if (theLexer.getLexemeType() != EOF_LEXEME) { 603 throw new IllegalArgumentException (); 604 } 605 606 int n = thePieces.size(); 608 myPieces = (String []) thePieces.toArray (new String [n]); 609 610 int i, j; 612 String temp; 613 for (i = 4; i < n; i += 2) { 614 j = 2; 615 while (j < i && myPieces[j].compareTo (myPieces[i]) <= 0) { 616 j += 2; 617 } 618 while (j < i) { 619 temp = myPieces[j]; 620 myPieces[j] = myPieces[i]; 621 myPieces[i] = temp; 622 temp = myPieces[j+1]; 623 myPieces[j+1] = myPieces[i+1]; 624 myPieces[i+1] = temp; 625 j += 2; 626 } 627 } 628 } 629 } 630 | Popular Tags |