On 05/15/2013 06:26 PM, Maxime Bégnis wrote:
Hello,

We finally solve the problem by using a Java applet accessed through
javascript to copy the xml content to the clipboard with a mime type of
"text/xml". It works fine when using it under linux, but not under
windows and I can't figure out why. Here is the very simple code I use
for the applet:

public class ClipboardApplet extends Applet implements ClipboardOwner {

     private Clipboard clipboard;

     @Override
     public void init() {
         clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
     }

     public boolean copy(final String mimeType, final String content) {
         clipboard.setContents(new DataHandler(content, mimeType), this);
         return true;
     }

     @Override
     public void lostOwnership(Clipboard clipboard, Transferable contents) {
         // Nothing
     }

}

The "copy" method is used by javascript:
ClipboardApplet.copy('text/xml', xmlCode);

xmlCode being for example:

<?xml version="1.0"?><ns:clipboard
ns2:inclusion="com.xmlmind.xml.xinclude.XInclude:href=&quot;http://localhost:9000/workspaces/GeneralElectric/content/en/fragments.xml&quot;
xpointer=&quot;lorem-ipsum&quot;" ns2:readOnly="true"
ns2:sourceURL="http://localhost:9000/workspaces/GeneralElectric/content/en/fragments.xml";
xmlns:ns2="http://www.xmlmind.com/xmleditor/namespace/property";
xmlns:ns="http://www.xmlmind.com/xmleditor/namespace/clipboard";><para
xmlns="http://docbook.org/ns/docbook"; xml:id="lorem-ipsum" vendor=""
role="check">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit
in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
officia deserunt mollit anim id est laborum.</para></ns:clipboard>

Am I doing something wrong here?

I don't see, but please note that I don't know what is DataHandler. (If it is:

http://docs.oracle.com/javaee/1.4/api/javax/activation/DataHandler.html

then I've never used this class. Internally, XXE uses com.xmlmind.xmledit.edit.XMLTransferable, whose thoroughly commented source code is attached to this email.)

May be there is nothing wrong at all. May be you are simply facing one of the many problems documented here:

http://www.xmlmind.com/xmleditor/known_problems.html#platform_independent

(Search for "Known problems related to the clipboard:")

As explained in my answer below, I did not recommend to follow this path. Therefore, I'm sorry but I don't see how I could help you solve your problem.




Thanks for your help.

Maxime Bégnis

On 04/05/2013 10:13, Hussein Shafie wrote:
On 05/03/2013 04:57 PM, Fabián Mandelbaum wrote:
Hussein, thanks for your answers, my remarks between lines:

    An external application copying some XML to the clipboard for use by
    XXE must now declare the copied data as being "application/xml" (or
    "text/xml").

    In a nutshell, XXE 5.6.0 makes a difference between "text/plain" and
    "application/xml", while XXE 5.4.0 ignored "application/xml" and
    ``sniffed'' the "text/plain" in order the detect the case where this
    text was actually XML (starts with "<?xml ").


So, we're kind of stuck... because it's not easy (or even possible?)
from Javascript to copy stuff to the clipboard, much less being able to
specify the media type (text/xml, for example) of the copied object...

I'm sure there's a very valid and well thought rationale behind this
change, but this is a feature breaker for us...

We're currently investigating the possibility to implement a small java
applet that will perform this copy-to-clipboard function to replace the
JavaScript implemented feature on our UI, but having an applet (on an
otherwise html+css+javascript-ONLY UI) just for this is not a very
elegant solution.

Will keep investigating about JavaScript and the clipboard (which seems
rather dead because, mainly, security constraints).


Don't worry, I'm sure we'll manage to solve this problem *cleanly*. So
please forget about hacks, at least for the moment.

I suggest to simply add a new scriptable method to the XXE applet.

References:

*
http://www.xmlmind.com/xmleditor/_distrib/doc/configure/integrating_the_applet.html#applet_scripting

*
http://www.xmlmind.com/xmleditor/_distrib/doc/api/com/xmlmind/xmleditapp/applet/Applet.html

This new scriptable method would allow to execute any command on the
active document view by passing to the applet a command name and a
command parameter. This mechanism can be used to copy an XML fragment
to the clipboard or to directly paste something into the active
document view.

On your JavaScript side:

1) Do you currently use Scriptable methods?

2) If the answer is no, why no?

3) If the answer is yes, do you currently have any  problem (e.g.
JavaScript security) with this?


/*
 * Copyright (c) 2013 Pixware SARL. All rights reserved.
 *
 * This file is part of the XMLmind XML Editor project.
 * For conditions of distribution and use, see the accompanying legal.txt file.
 */
package com.xmlmind.xmledit.edit;

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

/**
 * A {@link Transferable} allowing to transfer an XML string as 
 * {@link #APPLICATION_XML_FLAVOR} or {@link #TEXT_XML_FLAVOR}.
 */
public final class XMLTransferable implements Transferable,
                                              ClipboardOwner {
   /**
    * Corresponds to MIME Content-Type "<tt>application/xml</tt>",
    * the representation class being {@link java.lang.String}.
    */
    public static final DataFlavor APPLICATION_XML_FLAVOR =
        new DataFlavor("application/xml; class=java.lang.String", null);

    /**
     * Corresponds to MIME Content-Type "<tt>text/xml</tt>",
     * the representation class being {@link java.lang.String}.
     */
    public static final DataFlavor TEXT_XML_FLAVOR =
        new DataFlavor("text/xml; class=java.lang.String", null);

    /**
     * The XML string to be transfered. Starts with "<tt><?xml&nbsp;</tt>".
     */
    public final String xmlString;

    private final DataFlavor[] dataFlavors;

    private static final DataFlavor[] DATA_FLAVORS = new DataFlavor[] {
        APPLICATION_XML_FLAVOR,
        TEXT_XML_FLAVOR,
        TEXT_XML_FLAVOR
    };

    // -----------------------------------------------------------------------

    /**
     * Constructs a {@link Transferable} allowing to transfer specified XML
     * string.
     *
     * @param xmlString XML string to be transfered. Must start
     * with "<tt><?xml&nbsp;</tt>".
     */
    public XMLTransferable(String xmlString) {
        assert(xmlString != null && xmlString.startsWith("<?xml "));
        this.xmlString = xmlString;

        // Dirty trick used to force Java to report a FlavorEvent each time
        // XXE copies an XML fragment to the clipboard.
        // This is the only way we have found to detect a change 
        // in the XML content of the clipboard.
        // Of course, this only works between two instances of XXE.

        dataFlavors = DATA_FLAVORS.clone();
        StringBuilder buffer = new StringBuilder("application/x-xe-");
        buffer.append(Integer.toString(System.identityHashCode(this),
                                       Character.MAX_RADIX));
        buffer.append("+xml; class=java.lang.String");

        dataFlavors[2] = new DataFlavor(buffer.toString(), null);
    }

    public DataFlavor[] getTransferDataFlavors() {
        // Do not let client code change our array.
        return dataFlavors.clone();
    }

    public boolean isDataFlavorSupported(DataFlavor flavor) {
        for (DataFlavor f : dataFlavors) {
	    if (flavor.equals(f)) {
	        return true;
	    }
	}
	return false;
    }

    public Object getTransferData(DataFlavor flavor)
        throws UnsupportedFlavorException {
        for (DataFlavor f : dataFlavors) {
	    if (flavor.equals(f)) {
	        return xmlString;
	    }
	}

        throw new UnsupportedFlavorException(flavor);
    }

    /**
     * {@inheritDoc}
     * <p>Does nothing at all. Convenience allowing to specify
     * <code>clipboard.setContents(xmlTransferable, xmlTransferable)</code>
     */
    public void lostOwnership(Clipboard clipboard,
                              Transferable contents) {}
}


--
XMLmind XML Editor Support List
[email protected]
http://www.xmlmind.com/mailman/listinfo/xmleditor-support

Reply via email to