src/solaris/classes/sun/awt/X11/XDataTransferer.java

Print this page




  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 sun.awt.X11;
  27 
  28 import java.awt.Image;
  29 
  30 import java.awt.datatransfer.DataFlavor;
  31 import java.awt.datatransfer.Transferable;
  32 import java.awt.datatransfer.UnsupportedFlavorException;
  33 
  34 import java.awt.image.BufferedImage;
  35 import java.awt.image.ColorModel;
  36 import java.awt.image.WritableRaster;
  37 
  38 import java.io.BufferedReader;
  39 import java.io.InputStream;
  40 import java.io.InputStreamReader;
  41 import java.io.IOException;
  42 
  43 import java.net.URI;
  44 import java.net.URISyntaxException;
  45 
  46 import java.util.ArrayList;
  47 import java.util.Iterator;
  48 import java.util.LinkedHashSet;
  49 import java.util.List;
  50 
  51 import javax.imageio.ImageIO;
  52 import javax.imageio.ImageReader;
  53 import javax.imageio.ImageTypeSpecifier;
  54 import javax.imageio.ImageWriter;
  55 import javax.imageio.spi.ImageWriterSpi;
  56 

  57 import sun.awt.datatransfer.DataTransferer;
  58 import sun.awt.datatransfer.ToolkitThreadBlockedHandler;
  59 
  60 import java.io.ByteArrayOutputStream;
  61 import java.util.stream.Stream;
  62 
  63 /**
  64  * Platform-specific support for the data transfer subsystem.
  65  */
  66 public class XDataTransferer extends DataTransferer {
  67     static final XAtom FILE_NAME_ATOM = XAtom.get("FILE_NAME");
  68     static final XAtom DT_NET_FILE_ATOM = XAtom.get("_DT_NETFILE");
  69     static final XAtom PNG_ATOM = XAtom.get("PNG");
  70     static final XAtom JFIF_ATOM = XAtom.get("JFIF");
  71     static final XAtom TARGETS_ATOM = XAtom.get("TARGETS");
  72     static final XAtom INCR_ATOM = XAtom.get("INCR");
  73     static final XAtom MULTIPLE_ATOM = XAtom.get("MULTIPLE");
  74 
  75     /**
  76      * Singleton constructor
  77      */
  78     private XDataTransferer() {
  79     }
  80 
  81     private static XDataTransferer transferer;
  82 
  83     static synchronized XDataTransferer getInstanceImpl() {
  84         if (transferer == null) {
  85             transferer = new XDataTransferer();
  86         }
  87         return transferer;
  88     }
  89 

  90     public String getDefaultUnicodeEncoding() {
  91         return "iso-10646-ucs-2";
  92     }
  93 

  94     public boolean isLocaleDependentTextFormat(long format) {
  95         return false;
  96     }
  97 

  98     public boolean isTextFormat(long format) {
  99         return super.isTextFormat(format)
 100             || isMimeFormat(format, "text");
 101     }
 102 

 103     protected String getCharsetForTextFormat(Long lFormat) {
 104         long format = lFormat.longValue();
 105         if (isMimeFormat(format, "text")) {
 106             String nat = getNativeForFormat(format);
 107             DataFlavor df = new DataFlavor(nat, null);
 108             // Ignore the charset parameter of the MIME type if the subtype
 109             // doesn't support charset.
 110             if (!DataTransferer.doesSubtypeSupportCharset(df)) {
 111                 return null;
 112             }
 113             String charset = df.getParameter("charset");
 114             if (charset != null) {
 115                 return charset;
 116             }
 117         }
 118         return super.getCharsetForTextFormat(lFormat);
 119     }
 120 

 121     protected boolean isURIListFormat(long format) {
 122         String nat = getNativeForFormat(format);
 123         if (nat == null) {
 124             return false;
 125         }
 126         try {
 127             DataFlavor df = new DataFlavor(nat);
 128             if (df.getPrimaryType().equals("text") && df.getSubType().equals("uri-list")) {
 129                 return true;
 130             }
 131         } catch (Exception e) {
 132             // Not a MIME format.
 133         }
 134         return false;
 135     }
 136 

 137     public boolean isFileFormat(long format) {
 138         return format == FILE_NAME_ATOM.getAtom() ||
 139             format == DT_NET_FILE_ATOM.getAtom();
 140     }
 141 

 142     public boolean isImageFormat(long format) {
 143         return format == PNG_ATOM.getAtom() ||
 144             format == JFIF_ATOM.getAtom() ||
 145             isMimeFormat(format, "image");
 146     }
 147 

 148     protected Long getFormatForNativeAsLong(String str) {
 149         // Just get the atom. If it has already been retrived
 150         // once, we'll get a copy so this should be very fast.
 151         long atom = XAtom.get(str).getAtom();
 152         return Long.valueOf(atom);
 153     }
 154 

 155     protected String getNativeForFormat(long format) {
 156         return getTargetNameForAtom(format);
 157     }
 158 
 159     public ToolkitThreadBlockedHandler getToolkitThreadBlockedHandler() {
 160         return XToolkitThreadBlockedHandler.getToolkitThreadBlockedHandler();
 161     }
 162 
 163     /**
 164      * Gets an format name for a given format (atom)
 165      */
 166     private String getTargetNameForAtom(long atom) {
 167         return XAtom.get(atom).getName();
 168     }
 169 

 170     protected byte[] imageToPlatformBytes(Image image, long format)
 171       throws IOException {
 172         String mimeType = null;
 173         if (format == PNG_ATOM.getAtom()) {
 174             mimeType = "image/png";
 175         } else if (format == JFIF_ATOM.getAtom()) {
 176             mimeType = "image/jpeg";
 177         } else {
 178             // Check if an image MIME format.
 179             try {
 180                 String nat = getNativeForFormat(format);
 181                 DataFlavor df = new DataFlavor(nat);
 182                 String primaryType = df.getPrimaryType();
 183                 if ("image".equals(primaryType)) {
 184                     mimeType = df.getPrimaryType() + "/" + df.getSubType();
 185                 }
 186             } catch (Exception e) {
 187                 // Not an image MIME format.
 188             }
 189         }
 190         if (mimeType != null) {
 191             return imageToStandardBytes(image, mimeType);
 192         } else {
 193             String nativeFormat = getNativeForFormat(format);
 194             throw new IOException("Translation to " + nativeFormat +
 195                                   " is not supported.");
 196         }
 197     }
 198 

 199     protected ByteArrayOutputStream convertFileListToBytes(ArrayList<String> fileList)
 200         throws IOException
 201     {
 202         ByteArrayOutputStream bos = new ByteArrayOutputStream();
 203         for (int i = 0; i < fileList.size(); i++)
 204         {
 205                byte[] bytes = fileList.get(i).getBytes();
 206                if (i != 0) bos.write(0);
 207                bos.write(bytes, 0, bytes.length);
 208         }
 209         return bos;
 210     }
 211 
 212     /**
 213      * Translates either a byte array or an input stream which contain
 214      * platform-specific image data in the given format into an Image.
 215      */

 216     protected Image platformImageBytesToImage(
 217         byte[] bytes, long format) throws IOException
 218     {
 219         String mimeType = null;
 220         if (format == PNG_ATOM.getAtom()) {
 221             mimeType = "image/png";
 222         } else if (format == JFIF_ATOM.getAtom()) {
 223             mimeType = "image/jpeg";
 224         } else {
 225             // Check if an image MIME format.
 226             try {
 227                 String nat = getNativeForFormat(format);
 228                 DataFlavor df = new DataFlavor(nat);
 229                 String primaryType = df.getPrimaryType();
 230                 if ("image".equals(primaryType)) {
 231                     mimeType = df.getPrimaryType() + "/" + df.getSubType();
 232                 }
 233             } catch (Exception e) {
 234                 // Not an image MIME format.
 235             }


 300 
 301         return false;
 302     }
 303 
 304     /*
 305      * The XDnD protocol prescribes that the Atoms used as targets for data
 306      * transfer should have string names that represent the corresponding MIME
 307      * types.
 308      * To meet this requirement we check if the passed native format constitutes
 309      * a valid MIME and return a list of flavors to which the data in this MIME
 310      * type can be translated by the Data Transfer subsystem.
 311      */
 312     @Override
 313     public LinkedHashSet<DataFlavor> getPlatformMappingsForNative(String nat) {
 314         LinkedHashSet<DataFlavor> flavors = new LinkedHashSet<>();
 315 
 316         if (nat == null) {
 317             return flavors;
 318         }
 319 
 320         DataFlavor df = null;
 321 
 322         try {
 323             df = new DataFlavor(nat);
 324         } catch (Exception e) {
 325             // The string doesn't constitute a valid MIME type.
 326             return flavors;
 327         }
 328 
 329         DataFlavor value = df;
 330         final String primaryType = df.getPrimaryType();
 331         final String baseType = primaryType + "/" + df.getSubType();
 332 
 333         // For text formats we map natives to MIME strings instead of data
 334         // flavors to enable dynamic text native-to-flavor mapping generation.
 335         // See SystemFlavorMap.getFlavorsForNative() for details.
 336         if ("image".equals(primaryType)) {
 337             Iterator<ImageReader> readers = ImageIO.getImageReadersByMIMEType(baseType);
 338             if (readers.hasNext()) {
 339                 flavors.add(DataFlavor.imageFlavor);
 340             }
 341         }


 366     /*
 367      * The XDnD protocol prescribes that the Atoms used as targets for data
 368      * transfer should have string names that represent the corresponding MIME
 369      * types.
 370      * To meet this requirement we return a list of formats that represent
 371      * MIME types to which the data in this flavor can be translated by the Data
 372      * Transfer subsystem.
 373      */
 374     @Override
 375     public LinkedHashSet<String> getPlatformMappingsForFlavor(DataFlavor df) {
 376         LinkedHashSet<String> natives = new LinkedHashSet<>(1);
 377 
 378         if (df == null) {
 379             return natives;
 380         }
 381 
 382         String charset = df.getParameter("charset");
 383         String baseType = df.getPrimaryType() + "/" + df.getSubType();
 384         String mimeType = baseType;
 385 
 386         if (charset != null && DataTransferer.isFlavorCharsetTextType(df)) {
 387             mimeType += ";charset=" + charset;
 388         }
 389 
 390         // Add a mapping to the MIME native whenever the representation class
 391         // doesn't require translation.
 392         if (df.getRepresentationClass() != null &&
 393             (df.isRepresentationClassInputStream() ||
 394              df.isRepresentationClassByteBuffer() ||
 395              byte[].class.equals(df.getRepresentationClass()))) {
 396             natives.add(mimeType);
 397         }
 398 
 399         if (DataFlavor.imageFlavor.equals(df)) {
 400             String[] mimeTypes = ImageIO.getWriterMIMETypes();
 401             if (mimeTypes != null) {
 402                 for (String mime : mimeTypes) {
 403                     Iterator<ImageWriter> writers = ImageIO.getImageWritersByMIMEType(mime);
 404                     while (writers.hasNext()) {
 405                         ImageWriter imageWriter = writers.next();
 406                         ImageWriterSpi writerSpi = imageWriter.getOriginatingProvider();
 407 
 408                         if (writerSpi != null &&
 409                                 writerSpi.canEncodeImage(getDefaultImageTypeSpecifier())) {
 410                             natives.add(mime);
 411                             break;
 412                         }
 413                     }
 414                 }
 415             }
 416         } else if (DataTransferer.isFlavorCharsetTextType(df)) {
 417             // stringFlavor is semantically equivalent to the standard
 418             // "text/plain" MIME type.
 419             if (DataFlavor.stringFlavor.equals(df)) {
 420                 baseType = "text/plain";
 421             }
 422 
 423             for (String encoding : DataTransferer.standardEncodings()) {
 424                 if (!encoding.equals(charset)) {
 425                     natives.add(baseType + ";charset=" + encoding);
 426                 }
 427             }
 428 
 429             // Add a MIME format without specified charset.
 430             if (!natives.contains(baseType)) {
 431                 natives.add(baseType);
 432             }
 433         }
 434 
 435         return natives;
 436     }
 437 }


  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 sun.awt.X11;
  27 
  28 import java.awt.Image;
  29 
  30 import java.awt.datatransfer.DataFlavor;
  31 import java.awt.datatransfer.Transferable;

  32 
  33 import java.awt.image.BufferedImage;
  34 import java.awt.image.ColorModel;
  35 import java.awt.image.WritableRaster;
  36 
  37 import java.io.BufferedReader;
  38 import java.io.InputStream;
  39 import java.io.InputStreamReader;
  40 import java.io.IOException;
  41 
  42 import java.net.URI;
  43 import java.net.URISyntaxException;
  44 
  45 import java.util.ArrayList;
  46 import java.util.Iterator;
  47 import java.util.LinkedHashSet;

  48 
  49 import javax.imageio.ImageIO;
  50 import javax.imageio.ImageReader;
  51 import javax.imageio.ImageTypeSpecifier;
  52 import javax.imageio.ImageWriter;
  53 import javax.imageio.spi.ImageWriterSpi;
  54 
  55 import sun.datatransfer.DataFlavorUtil;
  56 import sun.awt.datatransfer.DataTransferer;
  57 import sun.awt.datatransfer.ToolkitThreadBlockedHandler;
  58 
  59 import java.io.ByteArrayOutputStream;

  60 
  61 /**
  62  * Platform-specific support for the data transfer subsystem.
  63  */
  64 public class XDataTransferer extends DataTransferer {
  65     static final XAtom FILE_NAME_ATOM = XAtom.get("FILE_NAME");
  66     static final XAtom DT_NET_FILE_ATOM = XAtom.get("_DT_NETFILE");
  67     static final XAtom PNG_ATOM = XAtom.get("PNG");
  68     static final XAtom JFIF_ATOM = XAtom.get("JFIF");
  69     static final XAtom TARGETS_ATOM = XAtom.get("TARGETS");
  70     static final XAtom INCR_ATOM = XAtom.get("INCR");
  71     static final XAtom MULTIPLE_ATOM = XAtom.get("MULTIPLE");
  72 
  73     /**
  74      * Singleton constructor
  75      */
  76     private XDataTransferer() {
  77     }
  78 
  79     private static XDataTransferer transferer;
  80 
  81     static synchronized XDataTransferer getInstanceImpl() {
  82         if (transferer == null) {
  83             transferer = new XDataTransferer();
  84         }
  85         return transferer;
  86     }
  87 
  88     @Override
  89     public String getDefaultUnicodeEncoding() {
  90         return "iso-10646-ucs-2";
  91     }
  92 
  93     @Override
  94     public boolean isLocaleDependentTextFormat(long format) {
  95         return false;
  96     }
  97 
  98     @Override
  99     public boolean isTextFormat(long format) {
 100         return super.isTextFormat(format)
 101             || isMimeFormat(format, "text");
 102     }
 103 
 104     @Override
 105     protected String getCharsetForTextFormat(Long lFormat) {
 106         if (isMimeFormat(lFormat, "text")) {
 107             String nat = getNativeForFormat(lFormat);

 108             DataFlavor df = new DataFlavor(nat, null);
 109             // Ignore the charset parameter of the MIME type if the subtype
 110             // doesn't support charset.
 111             if (!DataFlavorUtil.doesSubtypeSupportCharset(df)) {
 112                 return null;
 113             }
 114             String charset = df.getParameter("charset");
 115             if (charset != null) {
 116                 return charset;
 117             }
 118         }
 119         return super.getCharsetForTextFormat(lFormat);
 120     }
 121 
 122     @Override
 123     protected boolean isURIListFormat(long format) {
 124         String nat = getNativeForFormat(format);
 125         if (nat == null) {
 126             return false;
 127         }
 128         try {
 129             DataFlavor df = new DataFlavor(nat);
 130             if (df.getPrimaryType().equals("text") && df.getSubType().equals("uri-list")) {
 131                 return true;
 132             }
 133         } catch (Exception e) {
 134             // Not a MIME format.
 135         }
 136         return false;
 137     }
 138 
 139     @Override
 140     public boolean isFileFormat(long format) {
 141         return format == FILE_NAME_ATOM.getAtom() ||
 142             format == DT_NET_FILE_ATOM.getAtom();
 143     }
 144 
 145     @Override
 146     public boolean isImageFormat(long format) {
 147         return format == PNG_ATOM.getAtom() ||
 148             format == JFIF_ATOM.getAtom() ||
 149             isMimeFormat(format, "image");
 150     }
 151 
 152     @Override
 153     protected Long getFormatForNativeAsLong(String str) {
 154         // Just get the atom. If it has already been retrived
 155         // once, we'll get a copy so this should be very fast.
 156         return XAtom.get(str).getAtom();

 157     }
 158 
 159     @Override
 160     protected String getNativeForFormat(long format) {
 161         return getTargetNameForAtom(format);
 162     }
 163 
 164     public ToolkitThreadBlockedHandler getToolkitThreadBlockedHandler() {
 165         return XToolkitThreadBlockedHandler.getToolkitThreadBlockedHandler();
 166     }
 167 
 168     /**
 169      * Gets an format name for a given format (atom)
 170      */
 171     private String getTargetNameForAtom(long atom) {
 172         return XAtom.get(atom).getName();
 173     }
 174 
 175     @Override
 176     protected byte[] imageToPlatformBytes(Image image, long format)
 177       throws IOException {
 178         String mimeType = null;
 179         if (format == PNG_ATOM.getAtom()) {
 180             mimeType = "image/png";
 181         } else if (format == JFIF_ATOM.getAtom()) {
 182             mimeType = "image/jpeg";
 183         } else {
 184             // Check if an image MIME format.
 185             try {
 186                 String nat = getNativeForFormat(format);
 187                 DataFlavor df = new DataFlavor(nat);
 188                 String primaryType = df.getPrimaryType();
 189                 if ("image".equals(primaryType)) {
 190                     mimeType = df.getPrimaryType() + "/" + df.getSubType();
 191                 }
 192             } catch (Exception e) {
 193                 // Not an image MIME format.
 194             }
 195         }
 196         if (mimeType != null) {
 197             return imageToStandardBytes(image, mimeType);
 198         } else {
 199             String nativeFormat = getNativeForFormat(format);
 200             throw new IOException("Translation to " + nativeFormat +
 201                                   " is not supported.");
 202         }
 203     }
 204 
 205     @Override
 206     protected ByteArrayOutputStream convertFileListToBytes(ArrayList<String> fileList)
 207         throws IOException
 208     {
 209         ByteArrayOutputStream bos = new ByteArrayOutputStream();
 210         for (int i = 0; i < fileList.size(); i++)
 211         {
 212                byte[] bytes = fileList.get(i).getBytes();
 213                if (i != 0) bos.write(0);
 214                bos.write(bytes, 0, bytes.length);
 215         }
 216         return bos;
 217     }
 218 
 219     /**
 220      * Translates either a byte array or an input stream which contain
 221      * platform-specific image data in the given format into an Image.
 222      */
 223     @Override
 224     protected Image platformImageBytesToImage(
 225         byte[] bytes, long format) throws IOException
 226     {
 227         String mimeType = null;
 228         if (format == PNG_ATOM.getAtom()) {
 229             mimeType = "image/png";
 230         } else if (format == JFIF_ATOM.getAtom()) {
 231             mimeType = "image/jpeg";
 232         } else {
 233             // Check if an image MIME format.
 234             try {
 235                 String nat = getNativeForFormat(format);
 236                 DataFlavor df = new DataFlavor(nat);
 237                 String primaryType = df.getPrimaryType();
 238                 if ("image".equals(primaryType)) {
 239                     mimeType = df.getPrimaryType() + "/" + df.getSubType();
 240                 }
 241             } catch (Exception e) {
 242                 // Not an image MIME format.
 243             }


 308 
 309         return false;
 310     }
 311 
 312     /*
 313      * The XDnD protocol prescribes that the Atoms used as targets for data
 314      * transfer should have string names that represent the corresponding MIME
 315      * types.
 316      * To meet this requirement we check if the passed native format constitutes
 317      * a valid MIME and return a list of flavors to which the data in this MIME
 318      * type can be translated by the Data Transfer subsystem.
 319      */
 320     @Override
 321     public LinkedHashSet<DataFlavor> getPlatformMappingsForNative(String nat) {
 322         LinkedHashSet<DataFlavor> flavors = new LinkedHashSet<>();
 323 
 324         if (nat == null) {
 325             return flavors;
 326         }
 327 
 328         DataFlavor df;

 329         try {
 330             df = new DataFlavor(nat);
 331         } catch (Exception e) {
 332             // The string doesn't constitute a valid MIME type.
 333             return flavors;
 334         }
 335 
 336         DataFlavor value = df;
 337         final String primaryType = df.getPrimaryType();
 338         final String baseType = primaryType + "/" + df.getSubType();
 339 
 340         // For text formats we map natives to MIME strings instead of data
 341         // flavors to enable dynamic text native-to-flavor mapping generation.
 342         // See SystemFlavorMap.getFlavorsForNative() for details.
 343         if ("image".equals(primaryType)) {
 344             Iterator<ImageReader> readers = ImageIO.getImageReadersByMIMEType(baseType);
 345             if (readers.hasNext()) {
 346                 flavors.add(DataFlavor.imageFlavor);
 347             }
 348         }


 373     /*
 374      * The XDnD protocol prescribes that the Atoms used as targets for data
 375      * transfer should have string names that represent the corresponding MIME
 376      * types.
 377      * To meet this requirement we return a list of formats that represent
 378      * MIME types to which the data in this flavor can be translated by the Data
 379      * Transfer subsystem.
 380      */
 381     @Override
 382     public LinkedHashSet<String> getPlatformMappingsForFlavor(DataFlavor df) {
 383         LinkedHashSet<String> natives = new LinkedHashSet<>(1);
 384 
 385         if (df == null) {
 386             return natives;
 387         }
 388 
 389         String charset = df.getParameter("charset");
 390         String baseType = df.getPrimaryType() + "/" + df.getSubType();
 391         String mimeType = baseType;
 392 
 393         if (charset != null && DataFlavorUtil.isFlavorCharsetTextType(df)) {
 394             mimeType += ";charset=" + charset;
 395         }
 396 
 397         // Add a mapping to the MIME native whenever the representation class
 398         // doesn't require translation.
 399         if (df.getRepresentationClass() != null &&
 400             (df.isRepresentationClassInputStream() ||
 401              df.isRepresentationClassByteBuffer() ||
 402              byte[].class.equals(df.getRepresentationClass()))) {
 403             natives.add(mimeType);
 404         }
 405 
 406         if (DataFlavor.imageFlavor.equals(df)) {
 407             String[] mimeTypes = ImageIO.getWriterMIMETypes();
 408             if (mimeTypes != null) {
 409                 for (String mime : mimeTypes) {
 410                     Iterator<ImageWriter> writers = ImageIO.getImageWritersByMIMEType(mime);
 411                     while (writers.hasNext()) {
 412                         ImageWriter imageWriter = writers.next();
 413                         ImageWriterSpi writerSpi = imageWriter.getOriginatingProvider();
 414 
 415                         if (writerSpi != null &&
 416                                 writerSpi.canEncodeImage(getDefaultImageTypeSpecifier())) {
 417                             natives.add(mime);
 418                             break;
 419                         }
 420                     }
 421                 }
 422             }
 423         } else if (DataFlavorUtil.isFlavorCharsetTextType(df)) {
 424             // stringFlavor is semantically equivalent to the standard
 425             // "text/plain" MIME type.
 426             if (DataFlavor.stringFlavor.equals(df)) {
 427                 baseType = "text/plain";
 428             }
 429 
 430             for (String encoding : DataFlavorUtil.standardEncodings()) {
 431                 if (!encoding.equals(charset)) {
 432                     natives.add(baseType + ";charset=" + encoding);
 433                 }
 434             }
 435 
 436             // Add a MIME format without specified charset.
 437             if (!natives.contains(baseType)) {
 438                 natives.add(baseType);
 439             }
 440         }
 441 
 442         return natives;
 443     }
 444 }