All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.haulmont.yarg.structure.xml.impl.DefaultXmlReader Maven / Gradle / Ivy

/*
 * Copyright 2013 Haulmont
 *
 * 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.
 */
package com.haulmont.yarg.structure.xml.impl;

import com.haulmont.yarg.exception.ReportingXmlException;
import com.haulmont.yarg.structure.*;
import com.haulmont.yarg.structure.impl.*;
import com.haulmont.yarg.structure.xml.XmlReader;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.xml.sax.SAXException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.SchemaFactory;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SuppressWarnings("unchecked")
public class DefaultXmlReader implements XmlReader {

    @Override
    public Report parseXml(String xml) throws IOException {
        try {
            SAXReader reader;
            try {
                SAXParserFactory factory = SAXParserFactory.newInstance();

                SchemaFactory schemaFactory =
                        SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");

                factory.setSchema(schemaFactory.newSchema(
                        new Source[]{new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream("reporting.xsd"))}));

                SAXParser parser = factory.newSAXParser();

                reader = new SAXReader(parser.getXMLReader());
            } catch (SAXException e) {
                throw new ReportingXmlException(String.format("An error occurred during loading reporting xsd. \\n[%s]", xml), e);
            } catch (ParserConfigurationException e) {
                throw new ReportingXmlException(String.format("An error occurred during loading reporting xsd. \\n[%s]", xml), e);
            }

            Document document = reader.read(new StringReader(xml));
            Element rootElement = document.getRootElement();
            Map templateMap = parseTemplates(rootElement);
            List reportParameters = parseInputParameters(rootElement);
            List reportFieldFormats = parseValueFormats(rootElement);
            BandBuilder rootBandDefinitionBuilder = new BandBuilder().name(BandData.ROOT_BAND_NAME);
            parseQueries(rootElement.element("rootBand"), rootBandDefinitionBuilder);
            parseChildBandDefinitions(rootElement.element("rootBand"), rootBandDefinitionBuilder);
            ReportBand rootBandDefinition = rootBandDefinitionBuilder.build();
            String reportName = rootElement.attribute("name").getText();
            ReportImpl report = new ReportImpl(reportName, templateMap, rootBandDefinition, reportParameters, reportFieldFormats);
            return report;
        } catch (DocumentException e) {
            throw new ReportingXmlException(String.format("An error occurred while parsing report xml. \\n[%s]", xml), e);
        } catch (FileNotFoundException e) {
            throw new ReportingXmlException(String.format("Could not find report template. \\n[%s]", xml), e);
        } catch (ClassNotFoundException e) {
            throw new ReportingXmlException(String.format("Report parameter class not found. \\n[%s]", xml), e);
        }
    }

    /**
     * Override this method to load files differently from basic file system way
     *
     * @param documentPath - path to document (file system path or other if overriden)
     * @throws FileNotFoundException
     */
    protected InputStream getDocumentContent(String documentPath) throws FileNotFoundException {
        return new FileInputStream(documentPath);
    }

    protected Map parseTemplates(Element rootElement) throws IOException {
        Element templatesElement = rootElement.element("templates");
        List templates = templatesElement.elements("template");
        Map templateMap = new HashMap();
        for (Element template : templates) {
            String code = template.attribute("code").getText();
            String documentName = template.attribute("documentName").getText();
            String documentPath = template.attribute("documentPath").getText();
            String outputType = template.attribute("outputType").getText();
            String outputNamePattern = template.attribute("outputNamePattern").getText();

            ReportTemplate reportTemplate = new ReportTemplateBuilder()
                    .code(code)
                    .documentName(documentName)
                    .documentPath(documentPath)
                    .documentContent(getDocumentContent(documentPath))
                    .outputType(ReportOutputType.getOutputTypeById(outputType))
                    .outputNamePattern(outputNamePattern).build();


            templateMap.put(reportTemplate.getCode(), reportTemplate);
        }

        return templateMap;
    }

    protected List parseInputParameters(Element rootElement) throws FileNotFoundException, ClassNotFoundException {
        List reportParameters = new ArrayList();

        Element inputParametersElement = rootElement.element("parameters");
        if (inputParametersElement != null) {
            List parameters = inputParametersElement.elements("parameter");
            for (Element parameter : parameters) {
                String name = parameter.attribute("name").getText();
                String alias = parameter.attribute("alias").getText();
                Boolean required = Boolean.valueOf(parameter.attribute("required").getText());
                Class type = Class.forName(parameter.attribute("class").getText());
                Attribute defaultValueAttr = parameter.attribute("defaultValue");
                String defaultValue = null;
                if (defaultValueAttr != null) {
                    defaultValue = defaultValueAttr.getText();
                }

                ReportParameterImpl reportParameter = new ReportParameterImpl(name, alias, required, type, defaultValue);
                reportParameters.add(reportParameter);
            }
        }

        return reportParameters;
    }

    protected List parseValueFormats(Element rootElement) throws FileNotFoundException, ClassNotFoundException {
        List reportParameters = new ArrayList();
        Element formatsElement = rootElement.element("formats");

        if (formatsElement != null) {
            List parameters = formatsElement.elements("format");
            for (Element parameter : parameters) {
                String name = parameter.attribute("name").getText();
                String format = parameter.attribute("format").getText();
                reportParameters.add(new ReportFieldFormatImpl(name, format));
            }
        }

        return reportParameters;
    }

    protected void parseChildBandDefinitions(Element bandDefinitionElement, BandBuilder parentBandDefinitionBuilder) throws FileNotFoundException, ClassNotFoundException {
        Element childrenBandsElement = bandDefinitionElement.element("bands");
        if (childrenBandsElement != null) {
            List childrenBands = childrenBandsElement.elements("band");
            for (Element childBandElement : childrenBands) {
                String childBandName = childBandElement.attribute("name").getText();
                BandOrientation orientation = BandOrientation.fromId(childBandElement.attribute("orientation").getText());
                BandBuilder childBandDefinitionBuilder =
                        new BandBuilder()
                                .name(childBandName)
                                .orientation(orientation);

                parseQueries(childBandElement, childBandDefinitionBuilder);
                parseChildBandDefinitions(childBandElement, childBandDefinitionBuilder);
                ReportBand childBandDefinition = childBandDefinitionBuilder.build();
                parentBandDefinitionBuilder.child(childBandDefinition);
            }
        }
    }

    private void parseQueries(Element bandElement, BandBuilder bandDefinitionBuilder) {
        Element reportQueriesElement = bandElement.element("queries");

        if (reportQueriesElement != null) {
            List reportQueryElements = reportQueriesElement.elements("query");
            for (Element queryElement : reportQueryElements) {
                String script = queryElement.element("script").getText();
                String type = queryElement.attribute("type").getText();
                String queryName = queryElement.attribute("name").getText();

                bandDefinitionBuilder.query(queryName, script, type);
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy