user3726374
user3726374

Reputation: 605

Escape ">" character in Eclipse EMF serialization

I am serializing an EMF EObject to file. This works fine and is all correct.

But: a third-party tool relies on escaping the > character, also for text fields. What is the cleanest way to do this? I would like to prevent post processing the serialized file. I could not find any export option which would enable this extended escaping.

Upvotes: 1

Views: 26

Answers (1)

user3726374
user3726374

Reputation: 605

There is no export option to do this. The way to go here is to override XMLSaveImpl. Also see https://github.com/eclipse-emf/org.eclipse.emf/discussions/57 .

This is my example code:

package org.eclipse.emf.ecore.xmi.impl;

import java.util.Map;

import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.xmi.XMLHelper;
import org.eclipse.emf.ecore.xmi.XMLResource;

public class CustomXMLSaveImpl extends XMLSaveImpl {

    public CustomXMLSaveImpl(final XMLHelper helper) {
        super(helper);
    }

    public CustomXMLSaveImpl(final Map<?, ?> options, final XMLHelper helper, final String encoding, final String xmlVersion) {
        super(options, helper, encoding, xmlVersion);
    }

    protected void init(XMLResource resource, Map<?, ?> options) {
        super.init(resource, options);
        overrideEscape(options);
    }

    /**
     * Replace the Escape instance with our custom version.
     */
    protected void overrideEscape(Map<?, ?> options) {
        if (this.escape == null) {
            return;
        }
        MyEscape myEscape = new MyEscape(options, encoding, xmlVersion);
        this.escape = myEscape;
    }

    protected static class MyEscape extends Escape {
        private static final int MAX_UTF_MAPPABLE_CODEPOINT = 0x10FFFF;
        private static final int MAX_LATIN1_MAPPABLE_CODEPOINT = 0xFF;
        private static final int MAX_ASCII_MAPPABLE_CODEPOINT = 0x7F;

        public MyEscape(Map<?, ?> options, String encoding, String xmlVersion) {
            String lineSeparator = (String) options.get(Resource.OPTION_LINE_DELIMITER);
            setLineFeed(lineSeparator);
            int maxSafeChar = MAX_UTF_MAPPABLE_CODEPOINT;
            if (encoding != null) {
                if (encoding.equalsIgnoreCase("ASCII") || encoding.equalsIgnoreCase("US-ASCII")) {
                    maxSafeChar = MAX_ASCII_MAPPABLE_CODEPOINT;
                } else if (encoding.equalsIgnoreCase("ISO-8859-1")) {
                    maxSafeChar = MAX_LATIN1_MAPPABLE_CODEPOINT;
                }
            }

            setMappingLimit(maxSafeChar);
            if (!"1.0".equals(xmlVersion)) {
                setAllowControlCharacters(true);
            }

            setUseCDATA(Boolean.TRUE.equals(options.get(XMLResource.OPTION_ESCAPE_USING_CDATA)));
        }

        @Override
        public String convertText(final String input) {
            String converted = super.convertText(input);
            return converted.replace(">", "&gt;");
        }

        @Override
        public String convert(final String input) {
            String converted = super.convertText(input);
            return converted.replace(">", "&gt;");
        }
    }
}

Upvotes: 0

Related Questions