src/share/classes/java/awt/datatransfer/DataFlavor.java

Print this page




   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.awt.datatransfer;
  27 
  28 import sun.awt.datatransfer.DataTransferer;
  29 import sun.reflect.misc.ReflectUtil;
  30 
  31 import java.io.ByteArrayInputStream;
  32 import java.io.CharArrayReader;
  33 import java.io.Externalizable;
  34 import java.io.IOException;
  35 import java.io.InputStream;
  36 import java.io.InputStreamReader;
  37 import java.io.ObjectInput;
  38 import java.io.ObjectOutput;
  39 import java.io.OptionalDataException;
  40 import java.io.Reader;
  41 import java.io.StringReader;
  42 import java.io.UnsupportedEncodingException;
  43 import java.nio.ByteBuffer;
  44 import java.nio.CharBuffer;
  45 import java.util.Arrays;
  46 import java.util.Collections;
  47 import java.util.Comparator;
  48 import java.util.Objects;
  49 
  50 import static sun.security.util.SecurityConstants.GET_CLASSLOADER_PERMISSION;
  51 
  52 /**
  53  * A {@code DataFlavor} provides meta information about data. {@code DataFlavor}
  54  * is typically used to access data on the clipboard, or during
  55  * a drag and drop operation.
  56  * <p>
  57  * An instance of {@code DataFlavor} encapsulates a content type as
  58  * defined in <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>
  59  * and <a href="http://www.ietf.org/rfc/rfc2046.txt">RFC 2046</a>.
  60  * A content type is typically referred to as a MIME type.
  61  * <p>
  62  * A content type consists of a media type (referred
  63  * to as the primary type), a subtype, and optional parameters. See
  64  * <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>
  65  * for details on the syntax of a MIME type.
  66  * <p>
  67  * The JRE data transfer implementation interprets the parameter &quot;class&quot;


 565     public String toString() {
 566         String string = getClass().getName();
 567         string += "["+paramString()+"]";
 568         return string;
 569     }
 570 
 571     private String paramString() {
 572         String params = "";
 573         params += "mimetype=";
 574         if (mimeType == null) {
 575             params += "null";
 576         } else {
 577             params += mimeType.getBaseType();
 578         }
 579         params += ";representationclass=";
 580         if (representationClass == null) {
 581            params += "null";
 582         } else {
 583            params += representationClass.getName();
 584         }
 585         if (DataTransferer.isFlavorCharsetTextType(this) &&
 586             (isRepresentationClassInputStream() ||
 587              isRepresentationClassByteBuffer() ||
 588              byte[].class.equals(representationClass)))
 589         {
 590             params += ";charset=" + DataTransferer.getTextCharset(this);
 591         }
 592         return params;
 593     }
 594 
 595     /**
 596      * Returns a <code>DataFlavor</code> representing plain text with Unicode
 597      * encoding, where:
 598      * <pre>
 599      *     representationClass = java.io.InputStream
 600      *     mimeType            = "text/plain;
 601      *                            charset=&lt;platform default Unicode encoding&gt;"
 602      * </pre>
 603      * Sun's implementation for Microsoft Windows uses the encoding <code>utf-16le</code>.
 604      * Sun's implementation for Solaris and Linux uses the encoding
 605      * <code>iso-10646-ucs-2</code>.
 606      *
 607      * @return a <code>DataFlavor</code> representing plain text
 608      *    with Unicode encoding
 609      * @since 1.3
 610      */
 611     public static final DataFlavor getTextPlainUnicodeFlavor() {
 612         String encoding = null;
 613         DataTransferer transferer = DataTransferer.getInstance();
 614         if (transferer != null) {
 615             encoding = transferer.getDefaultUnicodeEncoding();
 616         }
 617         return new DataFlavor(
 618             "text/plain;charset="+encoding
 619             +";class=java.io.InputStream", "Plain Text");
 620     }
 621 
 622     /**
 623      * Selects the best text <code>DataFlavor</code> from an array of <code>
 624      * DataFlavor</code>s. Only <code>DataFlavor.stringFlavor</code>, and
 625      * equivalent flavors, and flavors that have a primary MIME type of "text",
 626      * are considered for selection.
 627      * <p>
 628      * Flavors are first sorted by their MIME types in the following order:
 629      * <ul>
 630      * <li>"text/sgml"
 631      * <li>"text/xml"
 632      * <li>"text/html"
 633      * <li>"text/rtf"
 634      * <li>"text/enriched"
 635      * <li>"text/richtext"
 636      * <li>"text/uri-list"
 637      * <li>"text/tab-separated-values"
 638      * <li>"text/t140"


 724      * <code>java.io.InputStream</code>, <code>java.nio.ByteBuffer</code>,
 725      * <code>[B</code>, &lt;all others&gt;.
 726      * <p>
 727      * If two or more flavors share the best representation class, or if no
 728      * flavor has one of the three specified representations, then one of those
 729      * flavors will be chosen non-deterministically.
 730      *
 731      * @param availableFlavors an array of available <code>DataFlavor</code>s
 732      * @return the best (highest fidelity) flavor according to the rules
 733      *         specified above, or <code>null</code>,
 734      *         if <code>availableFlavors</code> is <code>null</code>,
 735      *         has zero length, or contains no text flavors
 736      * @since 1.3
 737      */
 738     public static final DataFlavor selectBestTextFlavor(
 739                                        DataFlavor[] availableFlavors) {
 740         if (availableFlavors == null || availableFlavors.length == 0) {
 741             return null;
 742         }
 743 
 744         if (textFlavorComparator == null) {
 745             textFlavorComparator = new TextFlavorComparator();
 746         }
 747 
 748         DataFlavor bestFlavor = Collections.max(Arrays.asList(availableFlavors),
 749                                                 textFlavorComparator);
 750 
 751         if (!bestFlavor.isFlavorTextType()) {
 752             return null;
 753         }
 754 
 755         return bestFlavor;
 756     }
 757 
 758     private static Comparator<DataFlavor> textFlavorComparator;
 759 
 760     static class TextFlavorComparator
 761             extends DataTransferer.DataFlavorComparator {
 762 
 763         /**
 764          * Compares two <code>DataFlavor</code> objects. Returns a negative
 765          * integer, zero, or a positive integer as the first
 766          * <code>DataFlavor</code> is worse than, equal to, or better than the
 767          * second.
 768          * <p>
 769          * <code>DataFlavor</code>s are ordered according to the rules outlined
 770          * for <code>selectBestTextFlavor</code>.
 771          *
 772          * @param flavor1 the first <code>DataFlavor</code> to be compared
 773          * @param flavor2 the second <code>DataFlavor</code> to be compared
 774          * @return a negative integer, zero, or a positive integer as the first
 775          *         argument is worse, equal to, or better than the second
 776          * @throws ClassCastException if either of the arguments is not an
 777          *         instance of <code>DataFlavor</code>
 778          * @throws NullPointerException if either of the arguments is
 779          *         <code>null</code>
 780          *
 781          * @see #selectBestTextFlavor
 782          */
 783         public int compare(DataFlavor flavor1, DataFlavor flavor2) {
 784             if (flavor1.isFlavorTextType()) {
 785                 if (flavor2.isFlavorTextType()) {
 786                     return super.compare(flavor1, flavor2);
 787                 } else {
 788                     return 1;
 789                 }
 790             } else if (flavor2.isFlavorTextType()) {
 791                 return -1;
 792             } else {
 793                 return 0;
 794             }
 795         }
 796     }
 797 
 798     /**
 799      * Gets a Reader for a text flavor, decoded, if necessary, for the expected
 800      * charset (encoding). The supported representation classes are
 801      * <code>java.io.Reader</code>, <code>java.lang.String</code>,
 802      * <code>java.nio.CharBuffer</code>, <code>[C</code>,
 803      * <code>java.io.InputStream</code>, <code>java.nio.ByteBuffer</code>,
 804      * and <code>[B</code>.
 805      * <p>
 806      * Because text flavors which do not support the charset parameter are
 807      * encoded in a non-standard format, this method should not be called for
 808      * such flavors. However, in order to maintain backward-compatibility,
 809      * if this method is called for such a flavor, this method will treat the
 810      * flavor as though it supports the charset parameter and attempt to
 811      * decode it accordingly. See <code>selectBestTextFlavor</code> for a list
 812      * of text flavors which do not support the charset parameter.
 813      *
 814      * @param transferable the <code>Transferable</code> whose data will be
 815      *        requested in this flavor
 816      *
 817      * @return a <code>Reader</code> to read the <code>Transferable</code>'s


 998             return false;
 999         }
1000         if (this == that) {
1001             return true;
1002         }
1003 
1004         if (!Objects.equals(this.getRepresentationClass(), that.getRepresentationClass())) {
1005             return false;
1006         }
1007 
1008         if (mimeType == null) {
1009             if (that.mimeType != null) {
1010                 return false;
1011             }
1012         } else {
1013             if (!mimeType.match(that.mimeType)) {
1014                 return false;
1015             }
1016 
1017             if ("text".equals(getPrimaryType())) {
1018                 if (DataTransferer.doesSubtypeSupportCharset(this)
1019                         && representationClass != null
1020                         && !isStandardTextRepresentationClass()) {
1021                     String thisCharset =
1022                             DataTransferer.canonicalName(this.getParameter("charset"));
1023                     String thatCharset =
1024                             DataTransferer.canonicalName(that.getParameter("charset"));
1025                     if (!Objects.equals(thisCharset, thatCharset)) {
1026                         return false;
1027                     }
1028                 }
1029 
1030                 if ("html".equals(getSubType())) {
1031                     String thisDocument = this.getParameter("document");
1032                     String thatDocument = that.getParameter("document");
1033                     if (!Objects.equals(thisDocument, thatDocument)) {
1034                         return false;
1035                     }
1036                 }
1037             }
1038         }
1039 
1040         return true;
1041     }
1042 
1043     /**
1044      * Compares only the <code>mimeType</code> against the passed in


1071      * @return a hash code for this <code>DataFlavor</code>
1072      */
1073     public int hashCode() {
1074         int total = 0;
1075 
1076         if (representationClass != null) {
1077             total += representationClass.hashCode();
1078         }
1079 
1080         if (mimeType != null) {
1081             String primaryType = mimeType.getPrimaryType();
1082             if (primaryType != null) {
1083                 total += primaryType.hashCode();
1084             }
1085 
1086             // Do not add subType.hashCode() to the total. equals uses
1087             // MimeType.match which reports a match if one or both of the
1088             // subTypes is '*', regardless of the other subType.
1089 
1090             if ("text".equals(primaryType)) {
1091                 if (DataTransferer.doesSubtypeSupportCharset(this)
1092                         && representationClass != null
1093                         && !isStandardTextRepresentationClass()) {
1094                     String charset = DataTransferer.canonicalName(getParameter("charset"));
1095                     if (charset != null) {
1096                         total += charset.hashCode();
1097                     }
1098                 }
1099 
1100                 if ("html".equals(getSubType())) {
1101                     String document = this.getParameter("document");
1102                     if (document != null) {
1103                         total += document.hashCode();
1104                     }
1105                 }
1106             }
1107         }
1108 
1109         return total;
1110     }
1111 
1112     /**
1113      * Identical to {@link #equals(DataFlavor)}.
1114      *


1263      *
1264      * @since 1.4
1265      */
1266     public boolean isRepresentationClassByteBuffer() {
1267         return java.nio.ByteBuffer.class.isAssignableFrom(representationClass);
1268     }
1269 
1270    /**
1271     * Returns true if the representation class can be serialized.
1272     * @return true if the representation class can be serialized
1273     */
1274 
1275     public boolean isRepresentationClassSerializable() {
1276         return java.io.Serializable.class.isAssignableFrom(representationClass);
1277     }
1278 
1279    /**
1280     * Returns true if the representation class is <code>Remote</code>.
1281     * @return true if the representation class is <code>Remote</code>
1282     */
1283 
1284     public boolean isRepresentationClassRemote() {
1285         return DataTransferer.isRemote(representationClass);
1286     }
1287 
1288    /**
1289     * Returns true if the <code>DataFlavor</code> specified represents
1290     * a serialized object.
1291     * @return true if the <code>DataFlavor</code> specified represents
1292     *   a Serialized Object
1293     */
1294 
1295     public boolean isFlavorSerializedObjectType() {
1296         return isRepresentationClassSerializable() && isMimeTypeEqual(javaSerializedObjectMimeType);
1297     }
1298 
1299     /**
1300      * Returns true if the <code>DataFlavor</code> specified represents
1301      * a remote object.
1302      * @return true if the <code>DataFlavor</code> specified represents
1303      *  a Remote Object
1304      */
1305 


1339      * <code>[B</code>. If the representation is
1340      * <code>java.io.InputStream</code>, <code>java.nio.ByteBuffer</code>, or
1341      * <code>[B</code>, then this flavor's <code>charset</code> parameter must
1342      * be supported by this implementation of the Java platform. If a charset
1343      * is not specified, then the platform default charset, which is always
1344      * supported, is assumed.
1345      * <p>
1346      * If this flavor does not support the charset parameter, its
1347      * representation must be <code>java.io.InputStream</code>,
1348      * <code>java.nio.ByteBuffer</code>, or <code>[B</code>.
1349      * <p>
1350      * See <code>selectBestTextFlavor</code> for a list of text flavors which
1351      * support the charset parameter.
1352      *
1353      * @return <code>true</code> if this <code>DataFlavor</code> is a valid
1354      *         text flavor as described above; <code>false</code> otherwise
1355      * @see #selectBestTextFlavor
1356      * @since 1.4
1357      */
1358     public boolean isFlavorTextType() {
1359         return (DataTransferer.isFlavorCharsetTextType(this) ||
1360                 DataTransferer.isFlavorNoncharsetTextType(this));
1361     }
1362 
1363    /**
1364     * Serializes this <code>DataFlavor</code>.
1365     */
1366 
1367    public synchronized void writeExternal(ObjectOutput os) throws IOException {
1368        if (mimeType != null) {
1369            mimeType.setParameter("humanPresentableName", humanPresentableName);
1370            os.writeObject(mimeType);
1371            mimeType.removeParameter("humanPresentableName");
1372        } else {
1373            os.writeObject(null);
1374        }
1375 
1376        os.writeObject(representationClass);
1377    }
1378 
1379    /**
1380     * Restores this <code>DataFlavor</code> from a Serialized state.




   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.awt.datatransfer;
  27 
  28 import sun.datatransfer.DataFlavorUtil;
  29 import sun.reflect.misc.ReflectUtil;
  30 
  31 import java.io.ByteArrayInputStream;
  32 import java.io.CharArrayReader;
  33 import java.io.Externalizable;
  34 import java.io.IOException;
  35 import java.io.InputStream;
  36 import java.io.InputStreamReader;
  37 import java.io.ObjectInput;
  38 import java.io.ObjectOutput;
  39 import java.io.OptionalDataException;
  40 import java.io.Reader;
  41 import java.io.StringReader;
  42 import java.io.UnsupportedEncodingException;
  43 import java.nio.ByteBuffer;
  44 import java.nio.CharBuffer;
  45 import java.util.Arrays;
  46 import java.util.Collections;

  47 import java.util.Objects;
  48 
  49 import static sun.security.util.SecurityConstants.GET_CLASSLOADER_PERMISSION;
  50 
  51 /**
  52  * A {@code DataFlavor} provides meta information about data. {@code DataFlavor}
  53  * is typically used to access data on the clipboard, or during
  54  * a drag and drop operation.
  55  * <p>
  56  * An instance of {@code DataFlavor} encapsulates a content type as
  57  * defined in <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>
  58  * and <a href="http://www.ietf.org/rfc/rfc2046.txt">RFC 2046</a>.
  59  * A content type is typically referred to as a MIME type.
  60  * <p>
  61  * A content type consists of a media type (referred
  62  * to as the primary type), a subtype, and optional parameters. See
  63  * <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>
  64  * for details on the syntax of a MIME type.
  65  * <p>
  66  * The JRE data transfer implementation interprets the parameter &quot;class&quot;


 564     public String toString() {
 565         String string = getClass().getName();
 566         string += "["+paramString()+"]";
 567         return string;
 568     }
 569 
 570     private String paramString() {
 571         String params = "";
 572         params += "mimetype=";
 573         if (mimeType == null) {
 574             params += "null";
 575         } else {
 576             params += mimeType.getBaseType();
 577         }
 578         params += ";representationclass=";
 579         if (representationClass == null) {
 580            params += "null";
 581         } else {
 582            params += representationClass.getName();
 583         }
 584         if (DataFlavorUtil.isFlavorCharsetTextType(this) &&
 585             (isRepresentationClassInputStream() ||
 586              isRepresentationClassByteBuffer() ||
 587              byte[].class.equals(representationClass)))
 588         {
 589             params += ";charset=" + DataFlavorUtil.getTextCharset(this);
 590         }
 591         return params;
 592     }
 593 
 594     /**
 595      * Returns a <code>DataFlavor</code> representing plain text with Unicode
 596      * encoding, where:
 597      * <pre>
 598      *     representationClass = java.io.InputStream
 599      *     mimeType            = "text/plain;
 600      *                            charset=&lt;platform default Unicode encoding&gt;"
 601      * </pre>
 602      * Sun's implementation for Microsoft Windows uses the encoding <code>utf-16le</code>.
 603      * Sun's implementation for Solaris and Linux uses the encoding
 604      * <code>iso-10646-ucs-2</code>.
 605      *
 606      * @return a <code>DataFlavor</code> representing plain text
 607      *    with Unicode encoding
 608      * @since 1.3
 609      */
 610     public static final DataFlavor getTextPlainUnicodeFlavor() {





 611         return new DataFlavor(
 612             "text/plain;charset=" + DataFlavorUtil.getDesktopService().getDefaultUnicodeEncoding()
 613             +";class=java.io.InputStream", "Plain Text");
 614     }
 615 
 616     /**
 617      * Selects the best text <code>DataFlavor</code> from an array of <code>
 618      * DataFlavor</code>s. Only <code>DataFlavor.stringFlavor</code>, and
 619      * equivalent flavors, and flavors that have a primary MIME type of "text",
 620      * are considered for selection.
 621      * <p>
 622      * Flavors are first sorted by their MIME types in the following order:
 623      * <ul>
 624      * <li>"text/sgml"
 625      * <li>"text/xml"
 626      * <li>"text/html"
 627      * <li>"text/rtf"
 628      * <li>"text/enriched"
 629      * <li>"text/richtext"
 630      * <li>"text/uri-list"
 631      * <li>"text/tab-separated-values"
 632      * <li>"text/t140"


 718      * <code>java.io.InputStream</code>, <code>java.nio.ByteBuffer</code>,
 719      * <code>[B</code>, &lt;all others&gt;.
 720      * <p>
 721      * If two or more flavors share the best representation class, or if no
 722      * flavor has one of the three specified representations, then one of those
 723      * flavors will be chosen non-deterministically.
 724      *
 725      * @param availableFlavors an array of available <code>DataFlavor</code>s
 726      * @return the best (highest fidelity) flavor according to the rules
 727      *         specified above, or <code>null</code>,
 728      *         if <code>availableFlavors</code> is <code>null</code>,
 729      *         has zero length, or contains no text flavors
 730      * @since 1.3
 731      */
 732     public static final DataFlavor selectBestTextFlavor(
 733                                        DataFlavor[] availableFlavors) {
 734         if (availableFlavors == null || availableFlavors.length == 0) {
 735             return null;
 736         }
 737 




 738         DataFlavor bestFlavor = Collections.max(Arrays.asList(availableFlavors),
 739                                                 DataFlavorUtil.getTextFlavorComparator());
 740 
 741         if (!bestFlavor.isFlavorTextType()) {
 742             return null;
 743         }
 744 
 745         return bestFlavor;
 746     }
 747 








































 748     /**
 749      * Gets a Reader for a text flavor, decoded, if necessary, for the expected
 750      * charset (encoding). The supported representation classes are
 751      * <code>java.io.Reader</code>, <code>java.lang.String</code>,
 752      * <code>java.nio.CharBuffer</code>, <code>[C</code>,
 753      * <code>java.io.InputStream</code>, <code>java.nio.ByteBuffer</code>,
 754      * and <code>[B</code>.
 755      * <p>
 756      * Because text flavors which do not support the charset parameter are
 757      * encoded in a non-standard format, this method should not be called for
 758      * such flavors. However, in order to maintain backward-compatibility,
 759      * if this method is called for such a flavor, this method will treat the
 760      * flavor as though it supports the charset parameter and attempt to
 761      * decode it accordingly. See <code>selectBestTextFlavor</code> for a list
 762      * of text flavors which do not support the charset parameter.
 763      *
 764      * @param transferable the <code>Transferable</code> whose data will be
 765      *        requested in this flavor
 766      *
 767      * @return a <code>Reader</code> to read the <code>Transferable</code>'s


 948             return false;
 949         }
 950         if (this == that) {
 951             return true;
 952         }
 953 
 954         if (!Objects.equals(this.getRepresentationClass(), that.getRepresentationClass())) {
 955             return false;
 956         }
 957 
 958         if (mimeType == null) {
 959             if (that.mimeType != null) {
 960                 return false;
 961             }
 962         } else {
 963             if (!mimeType.match(that.mimeType)) {
 964                 return false;
 965             }
 966 
 967             if ("text".equals(getPrimaryType())) {
 968                 if (DataFlavorUtil.doesSubtypeSupportCharset(this)
 969                         && representationClass != null
 970                         && !isStandardTextRepresentationClass()) {
 971                     String thisCharset =
 972                             DataFlavorUtil.canonicalName(this.getParameter("charset"));
 973                     String thatCharset =
 974                             DataFlavorUtil.canonicalName(that.getParameter("charset"));
 975                     if (!Objects.equals(thisCharset, thatCharset)) {
 976                         return false;
 977                     }
 978                 }
 979 
 980                 if ("html".equals(getSubType())) {
 981                     String thisDocument = this.getParameter("document");
 982                     String thatDocument = that.getParameter("document");
 983                     if (!Objects.equals(thisDocument, thatDocument)) {
 984                         return false;
 985                     }
 986                 }
 987             }
 988         }
 989 
 990         return true;
 991     }
 992 
 993     /**
 994      * Compares only the <code>mimeType</code> against the passed in


1021      * @return a hash code for this <code>DataFlavor</code>
1022      */
1023     public int hashCode() {
1024         int total = 0;
1025 
1026         if (representationClass != null) {
1027             total += representationClass.hashCode();
1028         }
1029 
1030         if (mimeType != null) {
1031             String primaryType = mimeType.getPrimaryType();
1032             if (primaryType != null) {
1033                 total += primaryType.hashCode();
1034             }
1035 
1036             // Do not add subType.hashCode() to the total. equals uses
1037             // MimeType.match which reports a match if one or both of the
1038             // subTypes is '*', regardless of the other subType.
1039 
1040             if ("text".equals(primaryType)) {
1041                 if (DataFlavorUtil.doesSubtypeSupportCharset(this)
1042                         && representationClass != null
1043                         && !isStandardTextRepresentationClass()) {
1044                     String charset = DataFlavorUtil.canonicalName(getParameter("charset"));
1045                     if (charset != null) {
1046                         total += charset.hashCode();
1047                     }
1048                 }
1049 
1050                 if ("html".equals(getSubType())) {
1051                     String document = this.getParameter("document");
1052                     if (document != null) {
1053                         total += document.hashCode();
1054                     }
1055                 }
1056             }
1057         }
1058 
1059         return total;
1060     }
1061 
1062     /**
1063      * Identical to {@link #equals(DataFlavor)}.
1064      *


1213      *
1214      * @since 1.4
1215      */
1216     public boolean isRepresentationClassByteBuffer() {
1217         return java.nio.ByteBuffer.class.isAssignableFrom(representationClass);
1218     }
1219 
1220    /**
1221     * Returns true if the representation class can be serialized.
1222     * @return true if the representation class can be serialized
1223     */
1224 
1225     public boolean isRepresentationClassSerializable() {
1226         return java.io.Serializable.class.isAssignableFrom(representationClass);
1227     }
1228 
1229    /**
1230     * Returns true if the representation class is <code>Remote</code>.
1231     * @return true if the representation class is <code>Remote</code>
1232     */

1233     public boolean isRepresentationClassRemote() {
1234         return DataFlavorUtil.RMI.isRemote(representationClass);
1235     }
1236 
1237    /**
1238     * Returns true if the <code>DataFlavor</code> specified represents
1239     * a serialized object.
1240     * @return true if the <code>DataFlavor</code> specified represents
1241     *   a Serialized Object
1242     */
1243 
1244     public boolean isFlavorSerializedObjectType() {
1245         return isRepresentationClassSerializable() && isMimeTypeEqual(javaSerializedObjectMimeType);
1246     }
1247 
1248     /**
1249      * Returns true if the <code>DataFlavor</code> specified represents
1250      * a remote object.
1251      * @return true if the <code>DataFlavor</code> specified represents
1252      *  a Remote Object
1253      */
1254 


1288      * <code>[B</code>. If the representation is
1289      * <code>java.io.InputStream</code>, <code>java.nio.ByteBuffer</code>, or
1290      * <code>[B</code>, then this flavor's <code>charset</code> parameter must
1291      * be supported by this implementation of the Java platform. If a charset
1292      * is not specified, then the platform default charset, which is always
1293      * supported, is assumed.
1294      * <p>
1295      * If this flavor does not support the charset parameter, its
1296      * representation must be <code>java.io.InputStream</code>,
1297      * <code>java.nio.ByteBuffer</code>, or <code>[B</code>.
1298      * <p>
1299      * See <code>selectBestTextFlavor</code> for a list of text flavors which
1300      * support the charset parameter.
1301      *
1302      * @return <code>true</code> if this <code>DataFlavor</code> is a valid
1303      *         text flavor as described above; <code>false</code> otherwise
1304      * @see #selectBestTextFlavor
1305      * @since 1.4
1306      */
1307     public boolean isFlavorTextType() {
1308         return (DataFlavorUtil.isFlavorCharsetTextType(this) ||
1309                 DataFlavorUtil.isFlavorNoncharsetTextType(this));
1310     }
1311 
1312    /**
1313     * Serializes this <code>DataFlavor</code>.
1314     */
1315 
1316    public synchronized void writeExternal(ObjectOutput os) throws IOException {
1317        if (mimeType != null) {
1318            mimeType.setParameter("humanPresentableName", humanPresentableName);
1319            os.writeObject(mimeType);
1320            mimeType.removeParameter("humanPresentableName");
1321        } else {
1322            os.writeObject(null);
1323        }
1324 
1325        os.writeObject(representationClass);
1326    }
1327 
1328    /**
1329     * Restores this <code>DataFlavor</code> from a Serialized state.