Package de.timefinder.core.io.xml

Source Code of de.timefinder.core.io.xml.XmlExport

/*
*  Copyright 2010 Peter Karich, peat_hal 'at' users 'dot' sourceforge 'dot' net.
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*  under the License.
*/
package de.timefinder.core.io.xml;

import de.timefinder.algo.constraint.DifferentDayConstraint;
import de.timefinder.algo.constraint.EventOrderConstraint;
import de.timefinder.algo.constraint.MinGapsConstraint;
import de.timefinder.algo.constraint.PersonITCRasterConstraint;
import de.timefinder.algo.constraint.RasterConstraint;
import de.timefinder.core.io.text.ObjectWriting;
import de.timefinder.core.io.text.Writing;
import de.timefinder.core.util.WriterOutputStream;
import de.timefinder.data.ConstraintObject;
import de.timefinder.data.DBInterface;
import de.timefinder.data.DataPool;
import de.timefinder.data.Event;
import de.timefinder.data.Feature;
import de.timefinder.data.FeatureContainer;
import de.timefinder.data.Location;
import de.timefinder.data.Person;
import de.timefinder.data.Role;
import de.timefinder.data.access.Dao;
import de.timefinder.data.algo.Constraint;
import de.timefinder.data.algo.DataPoolSettings;
import de.timefinder.data.util.Helper;
import java.io.OutputStream;
import java.io.Writer;
import java.lang.reflect.Method;
import java.util.BitSet;
import java.util.Map;
import java.util.Map.Entry;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

/**
*
* @author Peter Karich, peat_hal 'at' users 'dot' sourceforge 'dot' net
*/
public class XmlExport extends AbstractXmlHelper {

    private OutputStream writer;
    private ObjectWriting objectWriting = new ObjectWriting();

    XmlExport(DataPool pool, DataPoolSettings settings, Writer writer) {
        this(pool, settings, new WriterOutputStream(writer));
    }

    public XmlExport(DataPool pool, DataPoolSettings settings, OutputStream writer) {
        super(pool, settings);
        if (writer == null)
            throw new NullPointerException("OutputStream cannot be null!");
        this.writer = writer;
    }

    public void doWork() {
        try {
            XMLWriter output = new XMLWriter(writer, new OutputFormat("  ", true));
            output.write(createDocument());
            output.close();
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    public Document createDocument() {
        Document document = DocumentHelper.createDocument();
        Element timefinderEl = document.addElement("timefinder"/*, "xmlnsValue"*/);
        timefinderEl.addAttribute("version", "4.1");

        writeElement(settings, timefinderEl);

        for (Dao<? extends DBInterface> dao : pool.getDaos()) {
            Element el = timefinderEl.addElement("objects");
            el.addAttribute("class", dao.getType().getName());

            for (DBInterface object : dao.getAll()) {
                if (object == null)
                    throw new NullPointerException("You should persist null objects!");

                if (Person.class.isAssignableFrom(dao.getType())) {
                    Element tmp = writeGeneric((Person) object, el, dao.getType());
                    writeElement((Person) object, tmp);
                } else if (Event.class.isAssignableFrom(dao.getType())) {
                    Element tmp = writeGeneric((Event) object, el, dao.getType());
                    writeElement((Event) object, tmp);
                } else if (Feature.class.isAssignableFrom(dao.getType())) {
                    writeGeneric((Feature) object, el, dao.getType());
                } else if (Location.class.isAssignableFrom(dao.getType())) {
                    Element tmp = writeGeneric((Location) object, el, dao.getType());
                    writeElement((Location) object, tmp);
                } else
                    throw new UnsupportedOperationException("Only person, feature, "
                            + "event and location are supported, but was:" + object.getClass());
            }
        }

        return document;
    }

    private void writeElement(DataPoolSettings settings, Element timefinderEl) {
        Element settingsEl = timefinderEl.addElement("settings");
        writeElements(settingsEl, settings, SETTINGS_PROPERTIES);
    }

    private void writeElement(Person person, Element element) {
        writeElements(element, person, PERSON_PROPERTIES);
        if (person.getEvents().size() == 0)
            return;

        Element newElement = element.addElement("eventsMap");
        for (Entry<Event, Role> entry : person.getEventsMap().entrySet()) {
            newElement.addElement("event").
                    addAttribute("ref", "" + entry.getKey().getId()).
                    addAttribute("role", entry.getValue().toString());
        }
    }

    private void writeElement(Event event, Element element) {
        writeElements(element, event, EVENT_PROPERTIES);
        writeFeatures(element, event);
        // write persons -> already done in person->events       
        // write location -> already done in location->events       
    }

    private void writeElement(Location location, Element element) {
        writeElements(element, location, LOCATION_PROPERTIES);
        writeFeatures(element, location);

        if (location.getEvents().size() == 0)
            return;

        Element newElement = element.addElement("events");
        for (Event ev : location.getEvents()) {
            newElement.addElement("event").addAttribute("ref", "" + ev.getId());
        }
    }

    private Element writeGeneric(ConstraintObject obj, Element element, Class concreteClass) {
        element = element.addElement("object");

        if (concreteClass != obj.getClass()) {
            element.addAttribute("class", obj.getClass().getName());
        }

        element.addAttribute("id", "" + obj.getId());
        element.addElement("name").setText(obj.getName());
        writeConstraints(element, obj);
        return element;
    }

    public Element writeConstraints(Element element, ConstraintObject co) {
        if (co.getConstraints().size() == 0)
            return element;

        Element newElement = element.addElement("constraints");
        for (Constraint constr : co.getConstraints()) {
            Element el = newElement.addElement(constr.getClass().getSimpleName());
            el.addAttribute("weight", "" + constr.getWeight());
            if (constr instanceof RasterConstraint) {
                RasterConstraint rc = (RasterConstraint) constr;
                Writing w = getWriting(BitSet.class);
                el.setText(w.toString(rc.getRaster().getForbidden()));
                el.addAttribute("length", "" + rc.getRaster().getForbidden().getLength());
            } else if (constr instanceof EventOrderConstraint) {
                EventOrderConstraint eoc = (EventOrderConstraint) constr;
                el.addElement("event").addAttribute("ref", "" + eoc.getEvent().getId());
                for (Event ev : eoc.getBefores()) {
                    el.addElement("beforeEvent").addAttribute("ref", "" + ev.getId());
                }
                for (Event ev : eoc.getFollows()) {
                    el.addElement("followsEvent").addAttribute("ref", "" + ev.getId());
                }
            } else if (constr instanceof PersonITCRasterConstraint) {
                PersonITCRasterConstraint pc = (PersonITCRasterConstraint) constr;
                el.addElement("person").addAttribute("ref", "" + pc.getPerson().getId());
            } else if (constr instanceof MinGapsConstraint) {
                MinGapsConstraint mgc = (MinGapsConstraint) constr;
                el.addAttribute("countEarly", "" + mgc.isCountEarly());
                for (Event ev : mgc.getEvents()) {
                    el.addElement("event").addAttribute("ref", "" + ev.getId());
                }
            } else if (constr instanceof DifferentDayConstraint) {
                DifferentDayConstraint ddc = (DifferentDayConstraint) constr;
                for (Event ev : ddc.getEvents()) {
                    el.addElement("event").addAttribute("ref", "" + ev.getId());
                }
            } else
                throw new UnsupportedOperationException("Constraint export/import not yet implemented for class " + constr.getClass().getName());

        }
        return element;
    }

    public Element writeFeatures(Element element, FeatureContainer fc) {
        if (fc.getFeatures().size() == 0)
            return element;

        Element newElement = element.addElement("features");
        for (Feature feature : fc.getFeatures()) {
            newElement.addElement("feature").addAttribute("ref", "" + feature.getId());
        }
        return element;
    }

    private Element writeElements(Element element, Object object, String... properties) {
        Map<String, Method> methods = Helper.findGetterMethods(object.getClass());
        for (String property : properties) {
            Method m = methods.get(property);
            try {
                if (m == null)
                    throw new IllegalStateException("No getter found for " + property);

                Object result = m.invoke(object);
                if (result != null) {
                    Writing writing = getWriting(m.getReturnType());
                    if (writing == null)
                        throw new UnsupportedOperationException("No writing found for " + m.getReturnType());

                    element.addElement(property).setText(writing.toString(result));
                }
            } catch (Exception ex) {
                throw new RuntimeException("exception while writing "
                        + property + " from "
                        + object.getClass().getName() + " " + object, ex);
            }
        }

        return element;
    }

    public Writing getWriting(Class clazz) {
        return objectWriting.getWriting(clazz);
    }
}
TOP

Related Classes of de.timefinder.core.io.xml.XmlExport

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.