org.openconcerto.xml.persistence.XMLFactory.java Source code

Java tutorial

Introduction

Here is the source code for org.openconcerto.xml.persistence.XMLFactory.java

Source

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
 * 
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each file.
 */

package org.openconcerto.xml.persistence;

import org.openconcerto.utils.ListMap;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.BidiMap;
import org.apache.commons.collections.bidimap.DualHashBidiMap;
import org.jdom.Element;

/**
 * Gre la transformation entre lment XML et objet Java.
 * 
 * @author ILM Informatique 29 juin 2004
 */
public class XMLFactory {

    static private final BidiMap elementNames = new DualHashBidiMap();
    static private final Map<Class, Method> methods = new HashMap<Class, Method>();

    /**
     * Doit tre appel par les XMLable pour dclarer le nom de leur lment XML.
     * 
     * @param elemName le nom de l'lment, eg "eleve".
     * @param clazz la classe, eg Eleve.class.
     * @throws IllegalArgumentException si clazz n'est pas un XMLable.
     * @throws IllegalArgumentException si la mthode fromXML n'est pas accessible dans clazz.
     */
    static public void addClass(String elemName, Class<?> clazz) {
        if (!XMLable.class.isAssignableFrom(clazz))
            throw new IllegalArgumentException("class is not a XMLable");
        try {
            final Method fromXML = clazz.getDeclaredMethod("fromXML", new Class[] { Element.class });
            methods.put(clazz, fromXML);
        } catch (SecurityException e) {
            throw new IllegalArgumentException("fromXML is not acessible in " + clazz);
        } catch (NoSuchMethodException e) {
            throw new IllegalArgumentException("fromXML is does not exist in " + clazz);
        }
        elementNames.put(elemName, clazz);
    }

    /**
     * Renvoie un objet  partir d'un lment XML.
     * 
     * @param elem l'lment XML.
     * @return l'objet Java correspondant.
     */
    public static XMLable fromXML(Element elem) {
        Class clazz = getClass(elem.getName());
        if (clazz == null)
            throw new IllegalArgumentException("class of element unknown:" + elem.getName() + ":" + elementNames);
        final Method fromXML = methods.get(clazz);
        XMLable obj = null;
        try {
            obj = (XMLable) fromXML.invoke(null, new Object[] { elem });
        } catch (IllegalArgumentException e) {
            // impossible
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // impossible, test dans addClass
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // fromXML ne renvoie pas d'exn
            throw (RuntimeException) e.getCause();
        }
        return obj;
    }

    /**
     * Transforme les lments XML passs en objets Java et les retourne dans une Map.
     * 
     * @param elems une collection d'Element.
     * @return un Map indexe par les classes des objets.
     */
    public static Map<Class<?>, List<XMLable>> fromXML(Collection<? extends Element> elems) {
        final ListMap<Class<?>, XMLable> res = new ListMap<Class<?>, XMLable>();
        for (final Element elem : elems) {
            final Class<?> clazz = getClass(elem.getName());
            if (clazz != null)
                res.add(clazz, fromXML(elem));
        }
        return res;
    }

    static public String getElementName(Class clazz) {
        return (String) elementNames.getKey(clazz);
    }

    public static String getNonNullElementName(Class clazz) {
        final String name = getElementName(clazz);
        if (name == null) {
            throw new IllegalStateException(clazz + " is not registered with addClass.");
        }
        return name;
    }

    static public Element getElement(Class clazz) {
        return new Element(getNonNullElementName(clazz));
    }

    static Class getClass(String element) {
        return (Class) elementNames.get(element);
    }

    public static Class getNonNullClass(String element) {
        final Class clazz = getClass(element);
        if (clazz == null) {
            throw new IllegalStateException(element + " is not registered with addClass.");
        }
        return clazz;
    }

}