alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (XDataTransferer.java)

This example Java source code file (XDataTransferer.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

arraylist, awt, bufferedimage, bufferedreader, bytearrayoutputstream, dataflavor, datatransfer, drop, image, imageio, imagetypespecifier, ioexception, iterator, override, string, translation, uri, util, xatom, xdatatransferer

The XDataTransferer.java Java example source code

/*
 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.awt.X11;

import java.awt.Image;

import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;

import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;

import java.net.URI;
import java.net.URISyntaxException;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.imageio.ImageIO;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriter;
import javax.imageio.spi.ImageWriterSpi;

import sun.awt.datatransfer.DataTransferer;
import sun.awt.datatransfer.ToolkitThreadBlockedHandler;

import java.io.ByteArrayOutputStream;

/**
 * Platform-specific support for the data transfer subsystem.
 */
public class XDataTransferer extends DataTransferer {
    static final XAtom FILE_NAME_ATOM = XAtom.get("FILE_NAME");
    static final XAtom DT_NET_FILE_ATOM = XAtom.get("_DT_NETFILE");
    static final XAtom PNG_ATOM = XAtom.get("PNG");
    static final XAtom JFIF_ATOM = XAtom.get("JFIF");
    static final XAtom TARGETS_ATOM = XAtom.get("TARGETS");
    static final XAtom INCR_ATOM = XAtom.get("INCR");
    static final XAtom MULTIPLE_ATOM = XAtom.get("MULTIPLE");

    /**
     * Singleton constructor
     */
    private XDataTransferer() {
    }

    private static XDataTransferer transferer;

    static XDataTransferer getInstanceImpl() {
        synchronized (XDataTransferer.class) {
            if (transferer == null) {
                transferer = new XDataTransferer();
            }
        }
        return transferer;
    }

    public String getDefaultUnicodeEncoding() {
        return "iso-10646-ucs-2";
    }

    public boolean isLocaleDependentTextFormat(long format) {
        return false;
    }

    public boolean isTextFormat(long format) {
        return super.isTextFormat(format)
            || isMimeFormat(format, "text");
    }

    protected String getCharsetForTextFormat(Long lFormat) {
        long format = lFormat.longValue();
        if (isMimeFormat(format, "text")) {
            String nat = getNativeForFormat(format);
            DataFlavor df = new DataFlavor(nat, null);
            // Ignore the charset parameter of the MIME type if the subtype
            // doesn't support charset.
            if (!DataTransferer.doesSubtypeSupportCharset(df)) {
                return null;
            }
            String charset = df.getParameter("charset");
            if (charset != null) {
                return charset;
            }
        }
        return super.getCharsetForTextFormat(lFormat);
    }

    protected boolean isURIListFormat(long format) {
        String nat = getNativeForFormat(format);
        if (nat == null) {
            return false;
        }
        try {
            DataFlavor df = new DataFlavor(nat);
            if (df.getPrimaryType().equals("text") && df.getSubType().equals("uri-list")) {
                return true;
            }
        } catch (Exception e) {
            // Not a MIME format.
        }
        return false;
    }

    public boolean isFileFormat(long format) {
        return format == FILE_NAME_ATOM.getAtom() ||
            format == DT_NET_FILE_ATOM.getAtom();
    }

    public boolean isImageFormat(long format) {
        return format == PNG_ATOM.getAtom() ||
            format == JFIF_ATOM.getAtom() ||
            isMimeFormat(format, "image");
    }

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

    protected String getNativeForFormat(long format) {
        return getTargetNameForAtom(format);
    }

    public ToolkitThreadBlockedHandler getToolkitThreadBlockedHandler() {
        return XToolkitThreadBlockedHandler.getToolkitThreadBlockedHandler();
    }

    /**
     * Gets an format name for a given format (atom)
     */
    private String getTargetNameForAtom(long atom) {
        return XAtom.get(atom).getName();
    }

    protected byte[] imageToPlatformBytes(Image image, long format)
      throws IOException {
        String mimeType = null;
        if (format == PNG_ATOM.getAtom()) {
            mimeType = "image/png";
        } else if (format == JFIF_ATOM.getAtom()) {
            mimeType = "image/jpeg";
        } else {
            // Check if an image MIME format.
            try {
                String nat = getNativeForFormat(format);
                DataFlavor df = new DataFlavor(nat);
                String primaryType = df.getPrimaryType();
                if ("image".equals(primaryType)) {
                    mimeType = df.getPrimaryType() + "/" + df.getSubType();
                }
            } catch (Exception e) {
                // Not an image MIME format.
            }
        }
        if (mimeType != null) {
            return imageToStandardBytes(image, mimeType);
        } else {
            String nativeFormat = getNativeForFormat(format);
            throw new IOException("Translation to " + nativeFormat +
                                  " is not supported.");
        }
    }

    protected ByteArrayOutputStream convertFileListToBytes(ArrayList<String> fileList)
        throws IOException
    {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        for (int i = 0; i < fileList.size(); i++)
        {
               byte[] bytes = fileList.get(i).getBytes();
               if (i != 0) bos.write(0);
               bos.write(bytes, 0, bytes.length);
        }
        return bos;
    }

    /**
     * Translates either a byte array or an input stream which contain
     * platform-specific image data in the given format into an Image.
     */
    protected Image platformImageBytesToImage(
        byte[] bytes, long format) throws IOException
    {
        String mimeType = null;
        if (format == PNG_ATOM.getAtom()) {
            mimeType = "image/png";
        } else if (format == JFIF_ATOM.getAtom()) {
            mimeType = "image/jpeg";
        } else {
            // Check if an image MIME format.
            try {
                String nat = getNativeForFormat(format);
                DataFlavor df = new DataFlavor(nat);
                String primaryType = df.getPrimaryType();
                if ("image".equals(primaryType)) {
                    mimeType = df.getPrimaryType() + "/" + df.getSubType();
                }
            } catch (Exception e) {
                // Not an image MIME format.
            }
        }
        if (mimeType != null) {
            return standardImageBytesToImage(bytes, mimeType);
        } else {
            String nativeFormat = getNativeForFormat(format);
            throw new IOException("Translation from " + nativeFormat +
                                  " is not supported.");
        }
    }

    @Override
    protected String[] dragQueryFile(byte[] bytes) {
        XToolkit.awtLock();
        try {
            return XlibWrapper.XTextPropertyToStringList(bytes,
                                                         XAtom.get("STRING").getAtom());
        } finally {
            XToolkit.awtUnlock();
        }
    }

    @Override
    protected URI[] dragQueryURIs(InputStream stream,
                                  long format,
                                  Transferable localeTransferable)
      throws IOException {

        String charset = null;
        if (localeTransferable != null &&
            isLocaleDependentTextFormat(format) &&
            localeTransferable.isDataFlavorSupported(javaTextEncodingFlavor)) {
            try {
                charset = new String(
                    (byte[])localeTransferable.getTransferData(javaTextEncodingFlavor),
                    "UTF-8"
                );
            } catch (UnsupportedFlavorException cannotHappen) {
            }
        } else {
            charset = getCharsetForTextFormat(format);
        }
        if (charset == null) {
            // Only happens when we have a custom text type.
            charset = getDefaultTextCharset();
        }

        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(stream, charset));
            String line;
            ArrayList<URI> uriList = new ArrayList();
            URI uri;
            while ((line = reader.readLine()) != null) {
                try {
                    uri = new URI(line);
                } catch (URISyntaxException uriSyntaxException) {
                    throw new IOException(uriSyntaxException);
                }
                uriList.add(uri);
            }
            return uriList.toArray(new URI[uriList.size()]);
        } finally {
            if (reader != null)
                reader.close();
        }
    }

    /**
     * Returns true if and only if the name of the specified format Atom
     * constitutes a valid MIME type with the specified primary type.
     */
    private boolean isMimeFormat(long format, String primaryType) {
        String nat = getNativeForFormat(format);

        if (nat == null) {
            return false;
        }

        try {
            DataFlavor df = new DataFlavor(nat);
            if (primaryType.equals(df.getPrimaryType())) {
                return true;
            }
        } catch (Exception e) {
            // Not a MIME format.
        }

        return false;
    }

    /*
     * The XDnD protocol prescribes that the Atoms used as targets for data
     * transfer should have string names that represent the corresponding MIME
     * types.
     * To meet this requirement we check if the passed native format constitutes
     * a valid MIME and return a list of flavors to which the data in this MIME
     * type can be translated by the Data Transfer subsystem.
     */
    public List <DataFlavor> getPlatformMappingsForNative(String nat) {
        List <DataFlavor> flavors = new ArrayList();

        if (nat == null) {
            return flavors;
        }

        DataFlavor df = null;

        try {
            df = new DataFlavor(nat);
        } catch (Exception e) {
            // The string doesn't constitute a valid MIME type.
            return flavors;
        }

        DataFlavor value = df;
        final String primaryType = df.getPrimaryType();
        final String baseType = primaryType + "/" + df.getSubType();

        // For text formats we map natives to MIME strings instead of data
        // flavors to enable dynamic text native-to-flavor mapping generation.
        // See SystemFlavorMap.getFlavorsForNative() for details.
        if ("image".equals(primaryType)) {
            Iterator readers = ImageIO.getImageReadersByMIMEType(baseType);
            if (readers.hasNext()) {
                flavors.add(DataFlavor.imageFlavor);
            }
        }

        flavors.add(value);

        return flavors;
    }

    private static ImageTypeSpecifier defaultSpecifier = null;

    private ImageTypeSpecifier getDefaultImageTypeSpecifier() {
        if (defaultSpecifier == null) {
            ColorModel model = ColorModel.getRGBdefault();
            WritableRaster raster =
                model.createCompatibleWritableRaster(10, 10);

            BufferedImage bufferedImage =
                new BufferedImage(model, raster, model.isAlphaPremultiplied(),
                                  null);

            defaultSpecifier = new ImageTypeSpecifier(bufferedImage);
        }

        return defaultSpecifier;
    }

    /*
     * The XDnD protocol prescribes that the Atoms used as targets for data
     * transfer should have string names that represent the corresponding MIME
     * types.
     * To meet this requirement we return a list of formats that represent
     * MIME types to which the data in this flavor can be translated by the Data
     * Transfer subsystem.
     */
    public List getPlatformMappingsForFlavor(DataFlavor df) {
        List natives = new ArrayList(1);

        if (df == null) {
            return natives;
        }

        String charset = df.getParameter("charset");
        String baseType = df.getPrimaryType() + "/" + df.getSubType();
        String mimeType = baseType;

        if (charset != null && DataTransferer.isFlavorCharsetTextType(df)) {
            mimeType += ";charset=" + charset;
        }

        // Add a mapping to the MIME native whenever the representation class
        // doesn't require translation.
        if (df.getRepresentationClass() != null &&
            (df.isRepresentationClassInputStream() ||
             df.isRepresentationClassByteBuffer() ||
             byteArrayClass.equals(df.getRepresentationClass()))) {
            natives.add(mimeType);
        }

        if (DataFlavor.imageFlavor.equals(df)) {
            String[] mimeTypes = ImageIO.getWriterMIMETypes();
            if (mimeTypes != null) {
                for (int i = 0; i < mimeTypes.length; i++) {
                    Iterator writers =
                        ImageIO.getImageWritersByMIMEType(mimeTypes[i]);

                    while (writers.hasNext()) {
                        ImageWriter imageWriter = (ImageWriter)writers.next();
                        ImageWriterSpi writerSpi =
                            imageWriter.getOriginatingProvider();

                        if (writerSpi != null &&
                            writerSpi.canEncodeImage(getDefaultImageTypeSpecifier())) {
                            natives.add(mimeTypes[i]);
                            break;
                        }
                    }
                }
            }
        } else if (DataTransferer.isFlavorCharsetTextType(df)) {
            // stringFlavor is semantically equivalent to the standard
            // "text/plain" MIME type.
            if (DataFlavor.stringFlavor.equals(df)) {
                baseType = "text/plain";
            }

            for (String encoding : DataTransferer.standardEncodings()) {
                if (!encoding.equals(charset)) {
                    natives.add(baseType + ";charset=" + encoding);
                }
            }

            // Add a MIME format without specified charset.
            if (!natives.contains(baseType)) {
                natives.add(baseType);
            }
        }

        return natives;
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java XDataTransferer.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.