eu.planets_project.pp.plato.xml.LibraryExport.java Source code

Java tutorial

Introduction

Here is the source code for eu.planets_project.pp.plato.xml.LibraryExport.java

Source

/*******************************************************************************
 * Copyright (c) 2006-2010 Vienna University of Technology, 
 * Department of Software Technology and Interactive Systems
 *
 * All rights reserved. This program and the accompanying
 * materials are made available under the terms of the
 * Apache License, Version 2.0 which accompanies
 * this distribution, and is available at
 * http://www.apache.org/licenses/LICENSE-2.0 
 *******************************************************************************/
package eu.planets_project.pp.plato.xml;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;

import org.apache.commons.digester.Digester;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.xml.sax.SAXException;

import eu.planets_project.pp.plato.model.tree.Leaf;
import eu.planets_project.pp.plato.model.tree.LibraryRequirement;
import eu.planets_project.pp.plato.model.tree.LibraryTree;
import eu.planets_project.pp.plato.model.tree.TreeNode;
import eu.planets_project.pp.plato.util.MeasurementInfoUri;
import eu.planets_project.pp.plato.xml.plato.CriterionCategoryFactory;

public class LibraryExport implements Serializable {

    private static final long serialVersionUID = -8034062583889766942L;

    public static OutputFormat prettyFormat = new OutputFormat(" ", true, "ISO-8859-1"); //OutputFormat.createPrettyPrint();
    public static OutputFormat compactFormat = new OutputFormat(null, false, "ISO-8859-1"); //OutputFormat.createPrettyPrint();

    public static Namespace xsi;
    public static Namespace platoLibNS;

    private LibraryTree lib;

    static {
        xsi = new Namespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
        platoLibNS = new Namespace("", "http://www.planets-project.eu/plato/library");
    }

    public void exportToStream(LibraryTree lib, OutputStream out) throws IOException {
        XMLWriter writer = new XMLWriter(out, prettyFormat);
        writer.write(exportToDocument(lib));
        writer.close();
    }

    public Document exportToDocument(LibraryTree lib) {
        Document doc = DocumentHelper.createDocument();

        Element root = doc.addElement("library");

        root.add(xsi);
        root.add(platoLibNS);
        //        root.addAttribute(xsi.getPrefix()+":schemaLocation", "http://www.planets-project.eu/plato plato-2.1.xsd");
        //        root.addAttribute(xsi.getPrefix()+":noNamespaceSchemaLocation", "http://www.ifs.tuwien.ac.at/dp/plato/schemas/plato-2.1.xsd");
        root.addAttribute("name", lib.getName());

        Element rootReq = root.addElement(new QName("requirement", platoLibNS));
        addRequirementProperties(rootReq, lib.getRoot());

        return doc;

    }

    private void addRequirementProperties(Element node, LibraryRequirement req) {
        addNodeAttributes(node, req);

        LibraryRequirement r = (LibraryRequirement) req;
        if (r.isPredefined()) {
            node.addAttribute("predefined", "" + r.isPredefined());
        }
        if (r.getCategory() != null) {
            node.addElement("category").addAttribute("name", r.getCategory().name());
        }

        Element children = node.addElement("refinedBy");
        for (TreeNode n : r.getChildren()) {
            addTreeFragment(children, n);
        }
    }

    private void addTreeFragment(Element parent, TreeNode node) {

        if (node instanceof LibraryRequirement) {
            Element req = parent.addElement("requirement");
            addRequirementProperties(req, (LibraryRequirement) node);
        } else {
            Leaf l = (Leaf) node;
            Element leaf = parent.addElement("criterion");
            addNodeAttributes(leaf, l);

            if (l.getMeasurementInfo().getUri() != null) {
                Element meas = leaf.addElement("measurementInfo");
                meas.addAttribute("uri", l.getMeasurementInfo().getUri());
            }
        }

    }

    private void addNodeAttributes(Element element, TreeNode node) {
        element.addAttribute("name", node.getName());
        addStringElement(element, "description", node.getDescription());
    }

    /**
     * TODO: move this to a dom4j utility library, it is copied from
     * {@link ProjectExporter}
     * 
     * Long strings are stored as XML-elements, not as attributes.
     * It is not possible to add an element with value <code>null</code>,
     * therefore this has to be handled here:
     * A new element is only added if there is a value at all.
     *
     * @param parent
     * @param name
     * @param value
     */
    private Element addStringElement(Element parent, String name, String value) {
        Element e = null;
        // &&(!"".equals(value)
        if (value != null) {
            e = parent.addElement(name);
            if (!"".equals(value)) {
                e.addText(value);
            }
        }
        return e;
    }

    public LibraryTree getLib() {
        return lib;
    }

    public void setLib(LibraryTree lib) {
        this.lib = lib;
    }

    public LibraryTree importFromStream(InputStream in) throws IOException, SAXException {
        lib = new LibraryTree();
        Digester d = new Digester();

        d.push(lib);
        d.addSetProperties("library");

        d.addObjectCreate("library/requirement", LibraryRequirement.class);
        d.addSetProperties("library/requirement");
        d.addSetNext("library/requirement", "setRoot");

        // some general rules
        d.addCallMethod("*/description", "setDescription", 0);

        // create category according to its name
        d.addFactoryCreate("*/category", CriterionCategoryFactory.class);
        d.addSetNext("*/category", "setCategory");

        // create requirements below root node
        d.addObjectCreate("*/refinedBy/requirement", LibraryRequirement.class);
        d.addSetProperties("*/refinedBy/requirement");
        d.addSetNext("*/refinedBy/requirement", "addChild");

        // create criteria
        d.addObjectCreate("*/criterion", Leaf.class);
        d.addSetProperties("*/criterion");
        d.addSetNext("*/criterion", "addChild");

        // and measurement infos if existent
        d.addObjectCreate("*/measurementInfo", MeasurementInfoUri.class);
        d.addSetProperties("*/measurementInfo", "uri", "asURI");
        d.addSetNext("*/measurementInfo", "setMeasurementInfo");

        d.parse(in);

        return lib;
    }

}