Frames | No Frames |
1: /* DocFlavor.java -- 2: Copyright (C) 2004, 2006 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package javax.print; 40: 41: import java.io.IOException; 42: import java.io.ObjectInputStream; 43: import java.io.Serializable; 44: import java.io.StreamTokenizer; 45: import java.io.StringReader; 46: import java.nio.charset.Charset; 47: import java.util.Iterator; 48: import java.util.Map; 49: import java.util.TreeMap; 50: 51: /** 52: * <code>DocFlavor</code> provides a description of the format in which the 53: * print data will be supplied in a print job to the print service. 54: * <p> 55: * A doc flavor consists of two parts: 56: * <ul> 57: * <li> 58: * The MIME type (Multipurpose Internet Mail Extensions types as described 59: * in RFC 2045/2046) specifying the media format of the print data. 60: * </li><li> 61: * The representation class name which is the fully qualified name of the 62: * class providing the print data to the print job. For example if the print 63: * data is supplied as a byte array the representation class name will be 64: * <code>"[B"</code> or for an input stream <code>"java.io.InputStream"</code>. 65: * </li> 66: * </ul> 67: * The <code>DocFlavor</code> class is therefore used in several places in the 68: * Java Print Service API. A print service provides its supported document 69: * flavors as an array of DocFlavor objects and a print job gets the flavor of 70: * its data to print from the <code>Doc</code> object provided as a DocFlavor 71: * instance. 72: * </p> 73: * <p> 74: * It has to be differentiated between <b>client formatted</b> and <b>service 75: * formatted</b> print data. Client formatted print data is already provided 76: * formatted by the client e.g. in an image format or as postscript. For 77: * service formatted print data, the Java Print Service instance produces 78: * the formatted print data. Here the doc flavor's representation class name 79: * does specify an interface instead of the actual print data source. The 80: * print service will call the methods of the given implementation of this 81: * interface with a special Graphics object capable of producing formatted 82: * print data from the graphics routines inside the interface methods. 83: * </p> 84: * <p> 85: * <h3>Client formatted print data document flavors</h3> 86: * The print service uses the representation class of the doc flavor to know 87: * how to retrieve the print data. If the representation class is a 88: * <code>URL</code> it will open the URL to read the print data from it. If it is 89: * a <code>byte[]</code> it will directly use the array and send it to the 90: * printer. There are predefined doc flavor as inner class for the most common 91: * representation class types: 92: * <ul> 93: * <li>Character arrays (<code>char[]</code>): The characters of the array 94: * represent the print data.</li> 95: * <li>Character streams (<code>java.io.Reader</code>): The whole characters 96: * read from the stream represent the print data.</li> 97: * <li>String (<code>java.lang.String</code>): The characters of the String 98: * represent the print data.</li> 99: * <li>Byte arrays (<code>byte[]</code>): The bytes of the array represent the 100: * print data. Encoding if text content is given in the mime type.</li> 101: * <li>Byte streams (<code>java.io.InputStream</code>): The whole bytes read 102: * from the stream represent the print data. If text content the encoding is 103: * specified in the mime type.</li> 104: * <li>Uniform Resource Locator (<code>java.net.URL</code>): The bytes read 105: * from the stream through opening of the URL represent the print data. 106: * If text content the encoding is specified in the mime type.</li></li> 107: * </ul> 108: * </p> 109: * <p> 110: * <h3>Service formatted print data document flavors</h3> 111: * The print service uses the provided object implementing the interface 112: * specified by the representation class to produce the formatted print data. 113: * The mime type of service formatted data is always 114: * <code>"application/x-java-jvm-local-objectref"</code> to signal the local 115: * reference to the print data object implementing the interface. Predefined 116: * doc flavor classes exist as an inner class for the three available interface 117: * to produce print data: 118: * <ul> 119: * <li>Pageable object (<code>java.awt.print.Pageable</code>): A pageable object 120: * is supplied to the print service. The print service will call the methods of 121: * the interface with a Grahics object to produce the formatted print data.</li> 122: * <li>Printable object (<code>java.awt.print.Printable</code>): A printable object 123: * is supplied to the print service. The print service will call the methods of 124: * the interface with a Grahics object to produce the formatted print data.</li> 125: * <li>Renderable Image object 126: * (<code>java.awt.image.renderable.RenderableImage</code>): A renderable image 127: * object is supplied to the print service. The print service calls methods of 128: * this interface to obtain the image to be printed.</li> 129: * </ul> 130: * </p> 131: * 132: * @author Michael Koch (konqueror@gmx.de) 133: * @author Wolfgang Baer (WBaer@gmx.de) 134: */ 135: public class DocFlavor implements Cloneable, Serializable 136: { 137: /** 138: * Predefined static <code>DocFlavor</code> objects for document 139: * types which use a byte array for the print data representation. 140: * <p>All the defined doc flavors have a print data representation 141: * classname of "[B" (byte array).</p> 142: * 143: * @author Michael Koch (konqueror@gmx.de) 144: */ 145: public static class BYTE_ARRAY 146: extends DocFlavor 147: { 148: private static final long serialVersionUID = -9065578006593857475L; 149: 150: /** 151: * Byte array doc flavor with a MIME Type of "application/octet-stream". 152: */ 153: public static final BYTE_ARRAY AUTOSENSE = new BYTE_ARRAY("application/octet-stream"); 154: /** 155: * Byte array doc flavor with a MIME Type of "image/gif". 156: */ 157: public static final BYTE_ARRAY GIF = new BYTE_ARRAY("image/gif"); 158: /** 159: * Byte array doc flavor with a MIME Type of "image/jpeg". 160: */ 161: public static final BYTE_ARRAY JPEG = new BYTE_ARRAY("image/jpeg"); 162: /** 163: * Byte array doc flavor with a MIME Type of "application/vnd.hp-PCL". 164: */ 165: public static final BYTE_ARRAY PCL = new BYTE_ARRAY("application/vnd.hp-PCL"); 166: /** 167: * Byte array doc flavor with a MIME Type of "application/pdf". 168: */ 169: public static final BYTE_ARRAY PDF = new BYTE_ARRAY("application/pdf"); 170: /** 171: * Byte array doc flavor with a MIME Type of "image/png". 172: */ 173: public static final BYTE_ARRAY PNG = new BYTE_ARRAY("image/png"); 174: /** 175: * Byte array doc flavor with a MIME Type of "application/postscript". 176: */ 177: public static final BYTE_ARRAY POSTSCRIPT = new BYTE_ARRAY("application/postscript"); 178: /** 179: * Byte array doc flavor with a MIME Type of "text/html" in the host encoding. 180: */ 181: public static final BYTE_ARRAY TEXT_HTML_HOST = new BYTE_ARRAY("text/html; charset=" + hostEncoding); 182: /** 183: * Byte array doc flavor with a MIME Type of "text/html; charset=us-ascii". 184: */ 185: public static final BYTE_ARRAY TEXT_HTML_US_ASCII = new BYTE_ARRAY("text/html; charset=us-ascii"); 186: /** 187: * Byte array doc flavor with a MIME Type of "text/html; charset=utf-16". 188: */ 189: public static final BYTE_ARRAY TEXT_HTML_UTF_16 = new BYTE_ARRAY("text/html; charset=utf-16"); 190: /** 191: * Byte array doc flavor with a MIME Type of "text/html; charset=utf-16be". 192: */ 193: public static final BYTE_ARRAY TEXT_HTML_UTF_16BE = new BYTE_ARRAY("text/html; charset=utf-16be"); 194: /** 195: * Byte array doc flavor with a MIME Type of "text/html; charset=utf-16le". 196: */ 197: public static final BYTE_ARRAY TEXT_HTML_UTF_16LE = new BYTE_ARRAY("text/html; charset=utf-16le"); 198: /** 199: * Byte array doc flavor with a MIME Type of "text/html; charset=utf-8". 200: */ 201: public static final BYTE_ARRAY TEXT_HTML_UTF_8 = new BYTE_ARRAY("text/html; charset=utf-8"); 202: /** 203: * Byte array doc flavor with a MIME Type of "text/plain" in the host encoding. 204: */ 205: public static final BYTE_ARRAY TEXT_PLAIN_HOST = new BYTE_ARRAY("text/plain; charset=" + hostEncoding); 206: /** 207: * Byte array doc flavor with a MIME Type of "text/plain; charset=us-ascii". 208: */ 209: public static final BYTE_ARRAY TEXT_PLAIN_US_ASCII = new BYTE_ARRAY("text/plain; charset=us-ascii"); 210: /** 211: * Byte array doc flavor with a MIME Type of "text/plain; charset=utf-16". 212: */ 213: public static final BYTE_ARRAY TEXT_PLAIN_UTF_16 = new BYTE_ARRAY("text/plain; charset=utf-16"); 214: /** 215: * Byte array doc flavor with a MIME Type of "text/plain; charset=utf-16be". 216: */ 217: public static final BYTE_ARRAY TEXT_PLAIN_UTF_16BE = new BYTE_ARRAY("text/plain; charset=utf-16be"); 218: /** 219: * Byte array doc flavor with a MIME Type of "text/plain; charset=utf-16le". 220: */ 221: public static final BYTE_ARRAY TEXT_PLAIN_UTF_16LE = new BYTE_ARRAY("text/plain; charset=utf-16le"); 222: /** 223: * Byte array doc flavor with a MIME Type of "text/plain; charset=utf-8". 224: */ 225: public static final BYTE_ARRAY TEXT_PLAIN_UTF_8 = new BYTE_ARRAY("text/plain; charset=utf-8"); 226: 227: /** 228: * Constructor for doc flavor objects with the given MIME type 229: * and a print data representation class name of "[B". 230: * 231: * @param mimeType the mime type string 232: * 233: * @throws NullPointerException if mimeType is <code>null</code>. 234: * @throws IllegalArgumentException if mimeType has the wrong syntax. 235: */ 236: public BYTE_ARRAY(String mimeType) 237: { 238: super(mimeType, "[B"); 239: } 240: } 241: 242: /** 243: * Predefined static <code>DocFlavor</code> objects for document 244: * types which use a char array for the print data representation. 245: * <p>All the defined doc flavors have a print data representation 246: * classname of "[C" (char array).</p> 247: * 248: * @author Michael Koch (konqueror@gmx.de) 249: */ 250: public static class CHAR_ARRAY 251: extends DocFlavor 252: { 253: private static final long serialVersionUID = -8720590903724405128L; 254: 255: /** 256: * Char array doc flavor with a MIME Type of "text/html; charset=utf-16". 257: */ 258: public static final DocFlavor.CHAR_ARRAY TEXT_HTML = new CHAR_ARRAY("text/html; charset=utf-16"); 259: /** 260: * Char array doc flavor with a MIME Type of "text/plain; charset=utf-16". 261: */ 262: public static final DocFlavor.CHAR_ARRAY TEXT_PLAIN = new CHAR_ARRAY("text/plain; charset=utf-16"); 263: 264: /** 265: * Constructor for doc flavor objects with the given MIME type 266: * and a print data representation class name of "[C". 267: * 268: * @param mimeType the mime type string 269: * 270: * @throws NullPointerException if mimeType is <code>null</code>. 271: * @throws IllegalArgumentException if mimeType has the wrong syntax. 272: */ 273: public CHAR_ARRAY(String mimeType) 274: { 275: super(mimeType, "[C"); 276: } 277: } 278: 279: /** 280: * Predefined static <code>DocFlavor</code> objects for document 281: * types which use an InputStream to retrieve the print data. 282: * <p>All the defined doc flavors have a print data representation 283: * classname of "java.io.InputStream".</p> 284: * 285: * @author Michael Koch (konqueror@gmx.de) 286: */ 287: public static class INPUT_STREAM 288: extends DocFlavor 289: { 290: private static final long serialVersionUID = -7045842700749194127L; 291: 292: /** 293: * InputStream doc flavor with a MIME Type of "application/octet-stream". 294: */ 295: public static final INPUT_STREAM AUTOSENSE = new INPUT_STREAM("application/octet-stream"); 296: /** 297: * InputStream doc flavor with a MIME Type of "image/gif". 298: */ 299: public static final INPUT_STREAM GIF = new INPUT_STREAM("image/gif"); 300: /** 301: * InputStream doc flavor with a MIME Type of "image/jpeg". 302: */ 303: public static final INPUT_STREAM JPEG = new INPUT_STREAM("image/jpeg"); 304: /** 305: * InputStream doc flavor with a MIME Type of "application/vnd.hp-PCL". 306: */ 307: public static final INPUT_STREAM PCL = new INPUT_STREAM("application/vnd.hp-PCL"); 308: /** 309: * InputStream doc flavor with a MIME Type of "application/pdf". 310: */ 311: public static final INPUT_STREAM PDF = new INPUT_STREAM("application/pdf"); 312: /** 313: * InputStream doc flavor with a MIME Type of "image/png". 314: */ 315: public static final INPUT_STREAM PNG = new INPUT_STREAM("image/png"); 316: /** 317: * InputStream doc flavor with a MIME Type of "application/postscript". 318: */ 319: public static final INPUT_STREAM POSTSCRIPT = new INPUT_STREAM("application/postscript"); 320: /** 321: * InputStream doc flavor with a MIME Type of "text/html" in the host encoding. 322: */ 323: public static final INPUT_STREAM TEXT_HTML_HOST = new INPUT_STREAM("text/html; charset=" + hostEncoding); 324: /** 325: * InputStream doc flavor with a MIME Type of "text/html; charset=us-ascii". 326: */ 327: public static final INPUT_STREAM TEXT_HTML_US_ASCII = new INPUT_STREAM("text/html; charset=us-ascii"); 328: /** 329: * InputStream doc flavor with a MIME Type of "text/html; charset=utf-16". 330: */ 331: public static final INPUT_STREAM TEXT_HTML_UTF_16 = new INPUT_STREAM("text/html; charset=utf-16"); 332: /** 333: * InputStream doc flavor with a MIME Type of "text/html; charset=utf-16be". 334: */ 335: public static final INPUT_STREAM TEXT_HTML_UTF_16BE = new INPUT_STREAM("text/html; charset=utf-16be"); 336: /** 337: * InputStream doc flavor with a MIME Type of "text/html; charset=utf-16le". 338: */ 339: public static final INPUT_STREAM TEXT_HTML_UTF_16LE = new INPUT_STREAM("text/html; charset=utf-16le"); 340: /** 341: * InputStream doc flavor with a MIME Type of "text/html; charset=utf-8". 342: */ 343: public static final INPUT_STREAM TEXT_HTML_UTF_8 = new INPUT_STREAM("text/html; charset=utf-8"); 344: /** 345: * InputStream doc flavor with a MIME Type of "text/plain" in the host encoding. 346: */ 347: public static final INPUT_STREAM TEXT_PLAIN_HOST = new INPUT_STREAM("text/plain; charset=" + hostEncoding); 348: /** 349: * InputStream doc flavor with a MIME Type of "text/plain; charset=us-ascii". 350: */ 351: public static final INPUT_STREAM TEXT_PLAIN_US_ASCII = new INPUT_STREAM("text/plain; charset=us-ascii"); 352: /** 353: * InputStream doc flavor with a MIME Type of "text/plain; charset=utf-16". 354: */ 355: public static final INPUT_STREAM TEXT_PLAIN_UTF_16 = new INPUT_STREAM("text/plain; charset=utf-16"); 356: /** 357: * InputStream doc flavor with a MIME Type of "text/plain; charset=utf-16be". 358: */ 359: public static final INPUT_STREAM TEXT_PLAIN_UTF_16BE = new INPUT_STREAM("text/plain; charset=utf-16be"); 360: /** 361: * InputStream doc flavor with a MIME Type of "text/plain; charset=utf-16le". 362: */ 363: public static final INPUT_STREAM TEXT_PLAIN_UTF_16LE = new INPUT_STREAM("text/plain; charset=utf-16le"); 364: /** 365: * InputStream doc flavor with a MIME Type of "text/plain; charset=utf-8". 366: */ 367: public static final INPUT_STREAM TEXT_PLAIN_UTF_8 = new INPUT_STREAM("text/plain; charset=utf-8"); 368: 369: /** 370: * Constructor for doc flavor objects with the given MIME type 371: * and a print data representation class name of "java.io.InputStream". 372: * 373: * @param mimeType the mime type string 374: * 375: * @throws NullPointerException if mimeType is <code>null</code>. 376: * @throws IllegalArgumentException if mimeType has the wrong syntax. 377: */ 378: public INPUT_STREAM(String mimeType) 379: { 380: super(mimeType, "java.io.InputStream"); 381: } 382: } 383: 384: /** 385: * Predefined static <code>DocFlavor</code> objects for document 386: * types which use an Reader to retrieve the print data. 387: * <p>All the defined doc flavors have a print data representation 388: * classname of "java.io.Reader".</p> 389: * 390: * @author Michael Koch (konqueror@gmx.de) 391: */ 392: public static class READER 393: extends DocFlavor 394: { 395: private static final long serialVersionUID = 7100295812579351567L; 396: 397: /** 398: * Reader doc flavor with a MIME Type of "text/html; charset=utf-16". 399: */ 400: public static final DocFlavor.READER TEXT_HTML = new READER("text/html; charset=utf-16"); 401: /** 402: * Reader doc flavor with a MIME Type of "text/plain; charset=utf-16". 403: */ 404: public static final DocFlavor.READER TEXT_PLAIN = new READER("text/plain; charset=utf-16"); 405: 406: /** 407: * Constructor for doc flavor objects with the given MIME type 408: * and a print data representation class name of "java.io.Reader". 409: * 410: * @param mimeType the mime type string 411: * 412: * @throws NullPointerException if mimeType is <code>null</code>. 413: * @throws IllegalArgumentException if mimeType has the wrong syntax. 414: */ 415: public READER(String mimeType) 416: { 417: super(mimeType, "java.io.Reader"); 418: } 419: } 420: 421: /** 422: * Predefined static <code>DocFlavor</code> objects for document 423: * types which use service formatted print data. 424: * <p>All the defined doc flavors have a MIME type of 425: * "application/x-java-jvm-local-objectref".</p> 426: * 427: * @author Michael Koch (konqueror@gmx.de) 428: */ 429: public static class SERVICE_FORMATTED 430: extends DocFlavor 431: { 432: private static final long serialVersionUID = 6181337766266637256L; 433: 434: /** 435: * Service formatted doc flavor with a representation class of 436: * "java.awt.print.Pageable". 437: */ 438: public static final DocFlavor.SERVICE_FORMATTED PAGEABLE = new SERVICE_FORMATTED("java.awt.print.Pageable"); 439: /** 440: * Service formatted doc flavor with a representation class of 441: * "java.awt.print.Printable". 442: */ 443: public static final DocFlavor.SERVICE_FORMATTED PRINTABLE = new SERVICE_FORMATTED("java.awt.print.Printable"); 444: /** 445: * Service formatted doc flavor with a representation class of 446: * "java.awt.image.renderable.RenderableImage". 447: */ 448: public static final DocFlavor.SERVICE_FORMATTED RENDERABLE_IMAGE = new SERVICE_FORMATTED("java.awt.image.renderable.RenderableImage"); 449: 450: /** 451: * Constructor for doc flavor objects with a MIME type of 452: * "application/x-java-jvm-local-objectref" and the given 453: * print data representation classname. 454: * 455: * @param className the representation classname 456: * 457: * @throws NullPointerException if className is <code>null</code>. 458: */ 459: public SERVICE_FORMATTED(String className) 460: { 461: super("application/x-java-jvm-local-objectref", className); 462: } 463: } 464: 465: /** 466: * Predefined static <code>DocFlavor</code> objects for document 467: * types which use a String for the print data representation. 468: * <p>All the defined doc flavors have a print data representation 469: * classname of "java.lang.String".</p> 470: * 471: * @author Michael Koch (konqueror@gmx.de) 472: */ 473: public static class STRING 474: extends DocFlavor 475: { 476: private static final long serialVersionUID = 4414407504887034035L; 477: 478: /** 479: * String doc flavor with a MIME Type of "text/html; charset=utf-16". 480: */ 481: public static final DocFlavor.STRING TEXT_HTML = new STRING("text/html; charset=utf-16"); 482: /** 483: * String doc flavor with a MIME Type of "text/plain; charset=utf-16". 484: */ 485: public static final DocFlavor.STRING TEXT_PLAIN = new STRING("text/plain; charset=utf-16"); 486: 487: /** 488: * Constructor for doc flavor objects with the given MIME type 489: * and a print data representation class name of "java.lang.String". 490: * 491: * @param mimeType the mime type string 492: * 493: * @throws NullPointerException if mimeType is <code>null</code>. 494: * @throws IllegalArgumentException if mimeType has the wrong syntax. 495: */ 496: public STRING(String mimeType) 497: { 498: super(mimeType, "java.lang.String"); 499: } 500: } 501: 502: /** 503: * Predefined static <code>DocFlavor</code> objects for document 504: * types which have an URL where to retrieve the print data. 505: * <p>All the defined doc flavors have a print data representation 506: * classname of "java.net.URL".</p> 507: * 508: * @author Michael Koch (konqueror@gmx.de) 509: */ 510: public static class URL 511: extends DocFlavor 512: { 513: private static final long serialVersionUID = 2936725788144902062L; 514: 515: /** 516: * URL doc flavor with a MIME Type of "application/octet-stream". 517: */ 518: public static final DocFlavor.URL AUTOSENSE = new URL("application/octet-stream"); 519: /** 520: * URL doc flavor with a MIME Type of "image/gif". 521: */ 522: public static final DocFlavor.URL GIF = new URL("image/gif"); 523: /** 524: * URL doc flavor with a MIME Type of "image/jpeg". 525: */ 526: public static final DocFlavor.URL JPEG = new URL("image/jpeg"); 527: /** 528: * URL doc flavor with a MIME Type of "application/vnd.hp-PCL". 529: */ 530: public static final DocFlavor.URL PCL = new URL("application/vnd.hp-PCL"); 531: /** 532: * URL doc flavor with a MIME Type of "application/pdf". 533: */ 534: public static final DocFlavor.URL PDF = new URL("application/pdf"); 535: /** 536: * URL doc flavor with a MIME Type of "image/png". 537: */ 538: public static final DocFlavor.URL PNG = new URL("image/png"); 539: /** 540: * URL doc flavor with a MIME Type of "application/postscript". 541: */ 542: public static final DocFlavor.URL POSTSCRIPT = new URL("application/postscript"); 543: /** 544: * URL doc flavor with a MIME Type of "text/html" in the host encoding. 545: */ 546: public static final DocFlavor.URL TEXT_HTML_HOST = new URL("text/html; charset=" + hostEncoding); 547: /** 548: * URL doc flavor with a MIME Type of "text/html; charset=us-ascii". 549: */ 550: public static final DocFlavor.URL TEXT_HTML_US_ASCII = new URL("text/html; charset=us-ascii"); 551: /** 552: * URL doc flavor with a MIME Type of "text/html; charset=utf-16". 553: */ 554: public static final DocFlavor.URL TEXT_HTML_UTF_16 = new URL("text/html; charset=utf-16"); 555: /** 556: * URL doc flavor with a MIME Type of "text/html; charset=utf-16be". 557: */ 558: public static final DocFlavor.URL TEXT_HTML_UTF_16BE = new URL("text/html; charset=utf-16be"); 559: /** 560: * URL doc flavor with a MIME Type of "text/html; charset=utf-16le". 561: */ 562: public static final DocFlavor.URL TEXT_HTML_UTF_16LE = new URL("text/html; charset=utf-16le"); 563: /** 564: * URL doc flavor with a MIME Type of "text/html; charset=utf-8". 565: */ 566: public static final DocFlavor.URL TEXT_HTML_UTF_8 = new URL("text/html; charset=utf-8"); 567: /** 568: * URL doc flavor with a MIME Type of "text/plain" in the host encoding. 569: */ 570: public static final DocFlavor.URL TEXT_PLAIN_HOST = new URL("text/plain; charset=" + hostEncoding); 571: /** 572: * URL doc flavor with a MIME Type of "text/plain; charset=us-ascii". 573: */ 574: public static final DocFlavor.URL TEXT_PLAIN_US_ASCII = new URL("text/plain; charset=us-ascii"); 575: /** 576: * URL doc flavor with a MIME Type of "text/plain; charset=utf-16". 577: */ 578: public static final DocFlavor.URL TEXT_PLAIN_UTF_16 = new URL("text/plain; charset=utf-16"); 579: /** 580: * URL doc flavor with a MIME Type of "text/plain; charset=utf-16be". 581: */ 582: public static final DocFlavor.URL TEXT_PLAIN_UTF_16BE = new URL("text/plain; charset=utf-16be"); 583: /** 584: * URL doc flavor with a MIME Type of "text/plain; charset=utf-16le". 585: */ 586: public static final DocFlavor.URL TEXT_PLAIN_UTF_16LE = new URL("text/plain; charset=utf-16le"); 587: /** 588: * URL doc flavor with a MIME Type of "text/plain; charset=utf-8". 589: */ 590: public static final DocFlavor.URL TEXT_PLAIN_UTF_8 = new URL("text/plain; charset=utf-8"); 591: 592: /** 593: * Constructor for doc flavor objects with the given MIME type 594: * and a print data representation class name of "java.net.URL". 595: * 596: * @param mimeType the mime type string 597: * 598: * @throws NullPointerException if mimeType is <code>null</code>. 599: * @throws IllegalArgumentException if mimeType has the wrong syntax. 600: */ 601: public URL(String mimeType) 602: { 603: super(mimeType, "java.net.URL"); 604: } 605: } 606: 607: private static final long serialVersionUID = -4512080796965449721L; 608: 609: /** 610: * The string representing the host encoding. This is the encoding 611: * used in the predefined HOST doc flavors 612: * (e.g. {@link BYTE_ARRAY#TEXT_HTML_HOST}). 613: */ 614: public static final String hostEncoding = Charset.defaultCharset().name(); 615: 616: private transient String mediaSubtype; 617: private transient String mediaType; 618: private transient TreeMap params; 619: 620: // name as defined in Serialized Form JDK 1.4 621: private String myClassName; 622: 623: /** 624: * Constructs a <code>DocFlavor</code> object with the given MIME type and 625: * representation class name. 626: * 627: * @param mimeType the MIME type string. 628: * @param className the fully-qualified name of the representation class. 629: * 630: * @throws NullPointerException if mimeType or className are <code>null</code>. 631: * @throws IllegalArgumentException if given mimeType has syntax errors. 632: */ 633: public DocFlavor(String mimeType, String className) 634: { 635: if (mimeType == null || className == null) 636: throw new NullPointerException(); 637: 638: params = new TreeMap(); 639: parseMimeType(mimeType); 640: 641: myClassName = className; 642: } 643: 644: /** 645: * Parses the given string as MIME type. 646: * The mediatype, mediasubtype and all parameter/value 647: * combinations are extracted, comments are dropped. 648: * 649: * @param mimeType the string to parse 650: * @throws IllegalArgumentException if not conformant. 651: */ 652: private void parseMimeType(String mimeType) 653: { 654: int MEDIA = 1; 655: int MEDIASUB = 2; 656: int PARAM_NAME = 3; 657: int PARAM_VALUE = 4; 658: int COMMENT_START = 5; 659: 660: int state = 0; 661: int lastState = 0; // keeps track of state before comment 662: int tok; 663: 664: try 665: { 666: String paramName = null; 667: StreamTokenizer in = new StreamTokenizer(new StringReader(mimeType)); 668: in.resetSyntax(); 669: // Allowed characters are anything except: 670: // SPACE, CTLs (= Unicode characters U+0000 - U+001F and U+007F) 671: // and tspecials ( ) < > @ , ; : \ " / [ ] ? = 672: in.whitespaceChars(0x00, 0x20); 673: in.whitespaceChars(0x7F, 0x7F); 674: in.wordChars('A', 'Z'); 675: in.wordChars('a', 'z'); 676: in.wordChars('0', '9'); 677: in.wordChars(0xA0, 0xFF); 678: in.wordChars(0x21, 0x21); 679: in.wordChars(0x23, 0x27); 680: in.wordChars(0x2A, 0x2B); 681: in.wordChars(0x2D, 0x2E); 682: in.wordChars(0x5E, 0x60); 683: in.wordChars(0x7B, 0x7E); 684: in.quoteChar('"'); 685: 686: while ((tok = in.nextToken()) != StreamTokenizer.TT_EOF) 687: { 688: switch (tok) 689: { 690: case StreamTokenizer.TT_WORD: 691: if (state == 0) 692: { 693: mediaType = in.sval.toLowerCase(); 694: state = MEDIA; 695: break; 696: } 697: if (state == MEDIA) 698: { 699: mediaSubtype = in.sval.toLowerCase(); 700: state = MEDIASUB; 701: break; 702: } 703: // begin of parameters is either after mediasub or a parameter value 704: if (state == MEDIASUB || state == PARAM_VALUE) 705: { 706: paramName = in.sval.toLowerCase(); 707: state = PARAM_NAME; 708: break; 709: } 710: // a parameter always needs to follow a value 711: if (state == PARAM_NAME) 712: { 713: String paramValue = in.sval; 714: // if a charset param the value needs to be stored lowercase 715: if (paramName.equals("charset")) 716: paramValue = paramValue.toLowerCase(); 717: 718: state = PARAM_VALUE; 719: params.put(paramName, paramValue); 720: break; 721: } 722: if (state == COMMENT_START) 723: { 724: // ignore; 725: break; 726: } 727: break; 728: case '/': 729: // may only occur after the mediatype 730: if (state != MEDIA) 731: throw new IllegalArgumentException(); 732: 733: break; 734: case '=': 735: // may only occur after a parameter 736: if (state != PARAM_NAME) 737: throw new IllegalArgumentException(); 738: 739: break; 740: case ';': 741: // differentiates mime type and parameters/value combinations 742: if (state != MEDIASUB && state != PARAM_VALUE) 743: throw new IllegalArgumentException(); 744: 745: break; 746: case '(': // begin comment 747: lastState = state; 748: state = COMMENT_START; 749: break; 750: case ')': // end comment 751: state = lastState; 752: break; 753: // a parameter always needs to follow a value / or quoted value 754: case '"': 755: if (state == PARAM_NAME) 756: { 757: String paramValue = in.sval; 758: // if a charset param the value needs to be stored lowercase 759: if (paramName.equals("charset")) 760: paramValue = paramValue.toLowerCase(); 761: 762: state = PARAM_VALUE; 763: params.put(paramName, paramValue); 764: break; 765: } 766: 767: // only values may be quoted 768: throw new IllegalArgumentException(); 769: default: 770: // if any other char is observed its not allowed 771: throw new IllegalArgumentException(); 772: } 773: } 774: } 775: catch (IOException e) 776: { 777: // should not happen as mimetype str cannot be null 778: throw new InternalError("IOException during parsing String " + mimeType); 779: } 780: } 781: 782: /** 783: * Checks if this doc flavor object is equal to the given object. 784: * <p> 785: * Two doc flavor objects are considered equal if the provided object is not 786: * <code>null</code> and an instance of <code>DocFlavor</code>. The MIME 787: * types has to be equal in their media type, media subtype, their 788: * paramter/value combinations and the representation classname. 789: * </p> 790: * 791: * @param obj the object to test. 792: * @return <code>true</code> if equal, <code>false</code> otherwise. 793: */ 794: public boolean equals(Object obj) 795: { 796: if (! (obj instanceof DocFlavor)) 797: return false; 798: 799: DocFlavor tmp = (DocFlavor) obj; 800: 801: return (getMimeType().equals(tmp.getMimeType()) 802: && getRepresentationClassName().equals(tmp.getRepresentationClassName())); 803: } 804: 805: /** 806: * Returns the media subtype of this flavor object. 807: * A mimetype of "text/html; charset=us-ascii" will 808: * return "html" as the media subtype. 809: * 810: * @return The media subtype. 811: */ 812: public String getMediaSubtype() 813: { 814: return mediaSubtype; 815: } 816: 817: /** 818: * Returns the media type of this flavor object. 819: * A mimetype of "text/html; charset=us-ascii" will 820: * return "text" as the media type. 821: * 822: * @return The media type. 823: */ 824: public String getMediaType() 825: { 826: return mediaType; 827: } 828: 829: /** 830: * Returns the mime type of this flavor object. 831: * The mimetype will have every parameter value 832: * enclosed in quotes. 833: * 834: * @return The mime type. 835: */ 836: public String getMimeType() 837: { 838: String mimeType = getMediaType() + "/" + getMediaSubtype(); 839: Iterator it = params.entrySet().iterator(); 840: 841: while (it.hasNext()) 842: { 843: Map.Entry entry = (Map.Entry) it.next(); 844: mimeType += "; " + entry.getKey() + "=\"" + entry.getValue() + "\""; 845: } 846: 847: return mimeType; 848: } 849: 850: /** 851: * Returns the value for an optional parameter of the mime type of this 852: * flavor object. 853: * 854: * @param paramName the name of the parameter 855: * @return The value for the parameter, or <code>null</code> if none bound. 856: * @throws NullPointerException if paramName is <code>null</code>. 857: */ 858: public String getParameter(String paramName) 859: { 860: if (paramName == null) 861: throw new NullPointerException(); 862: 863: return (String) params.get(paramName.toLowerCase()); 864: } 865: 866: /** 867: * Returns the name of the representation class of this flavor object. 868: * 869: * @return The representation classname. 870: */ 871: public String getRepresentationClassName() 872: { 873: return myClassName; 874: } 875: 876: /** 877: * Returns a hash code for this doc flavor object. 878: * 879: * @return The hashcode. 880: */ 881: public int hashCode() 882: { 883: return ((mediaType.hashCode() 884: * mediaSubtype.hashCode() 885: * myClassName.hashCode()) ^ params.hashCode()); 886: } 887: 888: /** 889: * Returns a string representation of this doc flavor object. 890: * The returned string is of the form 891: * getMimeType() + "; class=\"" + getRepresentationClassName() + "\""; 892: * 893: * @return The constructed string representation. 894: */ 895: public String toString() 896: { 897: return getMimeType() + "; class=\"" + getRepresentationClassName() + "\""; 898: } 899: 900: // needs special treatment for serialization 901: private void readObject(ObjectInputStream stream) 902: throws IOException, ClassNotFoundException 903: { 904: params = new TreeMap(); 905: myClassName = (String) stream.readObject(); 906: parseMimeType((String) stream.readObject()); 907: } 908: 909: private void writeObject(java.io.ObjectOutputStream stream) 910: throws IOException 911: { 912: stream.writeObject(myClassName); 913: stream.writeObject(getMimeType()); 914: } 915: }