org.carrot2.workbench.core.helpers.SimpleXmlMemento.java Source code

Java tutorial

Introduction

Here is the source code for org.carrot2.workbench.core.helpers.SimpleXmlMemento.java

Source

/*
 * Carrot2 project.
 *
 * Copyright (C) 2002-2015, Dawid Weiss, Stanisaw Osiski.
 * All rights reserved.
 *
 * Refer to the full license file "carrot2.LICENSE"
 * in the root folder of the repository checkout or at:
 * http://www.carrot2.org/carrot2.LICENSE
 */

package org.carrot2.workbench.core.helpers;

import java.beans.Introspector;
import java.io.*;

import org.apache.commons.lang.StringUtils;
import org.carrot2.util.ExceptionUtils;
import org.carrot2.workbench.core.WorkbenchCorePlugin;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.XMLMemento;
import org.simpleframework.xml.Root;
import org.simpleframework.xml.core.Persister;

/**
 * Utilities for storing and reading preferences ({@link IMemento},
 * {@link IPreferenceStore}) using <code>org.simpleframework.xml</code> library.
 */
public final class SimpleXmlMemento {
    /**
     * Creates an {@link XMLMemento} from Simple XML-annotated bean.
     */
    static IMemento toMemento(Object benchmarkSettings) throws IOException {
        try {
            final StringWriter w = new StringWriter();
            new Persister().write(benchmarkSettings, w);
            XMLMemento memento = XMLMemento.createReadRoot(new StringReader(w.toString()));
            return memento;
        } catch (Exception e) {
            throw ExceptionUtils.wrapAs(IOException.class, e);
        }
    }

    /**
     * Reads an object from a {@link IMemento}. The memento's type (root) must equal the
     * bean's {@link Root} annotation name attribute.
     */
    static <T> T fromMemento(Class<T> clazz, IMemento memento) throws IOException {
        try {
            final StringWriter sw = new StringWriter();
            final XMLMemento m = XMLMemento.createWriteRoot(memento.getType());
            m.putMemento(memento);
            m.save(sw);
            return new Persister().read(clazz, new StringReader(sw.toString()));
        } catch (Exception e) {
            throw ExceptionUtils.wrapAs(IOException.class, e);
        }
    }

    /**
     * A shortcut for:
     * 
     * <pre>
     * fromMemento(clazz, memento.getChild(childName))
     * </pre>
     * 
     * verifying precondition that only one child of a given name exists.
     */
    static <T> T fromMemento(Class<T> clazz, IMemento memento, String childName) throws IOException {
        final IMemento[] children = memento.getChildren(childName);
        if (children.length != 1) {
            throw new IOException(
                    "Expected a single node named '" + childName + "' under memento '" + memento.getType() + "'.");
        }
        return fromMemento(clazz, children[0]);
    }

    /**
     * Convert any {@link IMemento} to a string.
     */
    public static String toString(IMemento memento) {
        if (!(memento instanceof XMLMemento)) {
            XMLMemento m = XMLMemento.createWriteRoot(memento.getType());
            m.putMemento(memento);
            memento = m;
        }

        try {
            final StringWriter w = new StringWriter();
            ((XMLMemento) memento).save(w);
            return w.toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Convert any <code>org.simpleframework.xml</code>-enabled object to an XML string.
     */
    public static String toString(Object object) throws IOException {
        checkObject(object);

        try {
            final StringWriter w = new StringWriter();
            new Persister().write(object, w);
            return w.toString();
        } catch (Exception e) {
            throw ExceptionUtils.wrapAs(IOException.class, e);
        }
    }

    /**
     * Convert an XML string to <code>org.simpleframework.xml</code>-enabled object.
     */
    public static <T> T fromString(Class<T> clazz, String xml) throws IOException {
        try {
            final StringReader r = new StringReader(xml);
            return new Persister().read(clazz, r);
        } catch (Exception e) {
            throw ExceptionUtils.wrapAs(IOException.class, e);
        }
    }

    /**
     * Add a child node to a given memento, named after the object's {@link Root}
     * annotation.
     */
    public static void addChild(IMemento memento, Object object) throws IOException {
        checkObject(object);

        final IMemento child = toMemento(object);
        memento.createChild(child.getType()).putMemento(child);
    }

    /**
     * Returns an object deserialized from a child node of a given memento.
     */
    public static <T> T getChild(Class<T> clazz, IMemento memento) throws IOException {
        Root root = clazz.getAnnotation(Root.class);

        if (root == null) {
            throw new IllegalArgumentException("Missing @Root annotation on: " + clazz.getName());
        }

        String childName = root.name();
        if (StringUtils.isEmpty(childName)) {
            childName = getClassName(clazz);
        }

        IMemento[] children = memento.getChildren(childName);
        if (children.length == 0) {
            return null;
        }

        if (children.length != 1) {
            throw new IOException("More than one child named '" + childName + "':" + children.length);
        }

        return fromMemento(clazz, children[0]);
    }

    /**
     * Save an object to global plugin's preference store.
     */
    public static void toPreferenceStore(String globalPreferenceKey, Object object) {
        final IPreferenceStore prefStore = WorkbenchCorePlugin.getDefault().getPreferenceStore();
        try {
            prefStore.setValue(globalPreferenceKey, toString(object));
        } catch (IOException e) {
            Utils.logError(e, false);
        }
    }

    /**
     * Read an object from the global plugin's preference store. May return
     * <code>null</code> if an error occurred. 
     */
    public static <T> T fromPreferenceStore(Class<T> clazz, String globalPreferenceKey) {
        final IPreferenceStore prefStore = WorkbenchCorePlugin.getDefault().getPreferenceStore();
        final String xml = prefStore.getString(globalPreferenceKey);
        if (!StringUtils.isEmpty(xml)) {
            try {
                return fromString(clazz, xml);
            } catch (IOException e) {
                Utils.logError(e, false);
            }
        }
        return null;
    }

    /**
     * Check if the target contains simple XML's annotation.
     */
    private static void checkObject(Object object) {
        Root root = object.getClass().getAnnotation(Root.class);
        if (root == null) {
            throw new IllegalArgumentException("Missing @Root annotation on: " + object.getClass());
        }
    }

    /**
     * Mimics SimpleXML's naming for classes without {@link Root#name()}.
     */
    private static String getClassName(Class<?> type) {
        if (type.isArray())
            type = type.getComponentType();
        final String name = type.getSimpleName();
        if (type.isPrimitive())
            return name;
        else
            return Introspector.decapitalize(name);
    }
}