Package com.haulmont.yarg.reporting

Source Code of com.haulmont.yarg.reporting.DataExtractorImpl

/*
* 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.
*/

/**
*
* @author degtyarjov
* @version $Id$
*/
package com.haulmont.yarg.reporting;

import com.google.common.base.Preconditions;
import com.haulmont.yarg.exception.DataLoadingException;
import com.haulmont.yarg.exception.ValidationException;
import com.haulmont.yarg.loaders.ReportDataLoader;
import com.haulmont.yarg.loaders.factory.ReportLoaderFactory;
import com.haulmont.yarg.structure.BandData;
import com.haulmont.yarg.structure.Report;
import com.haulmont.yarg.structure.ReportBand;
import com.haulmont.yarg.structure.ReportQuery;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;

import java.util.*;

public class DataExtractorImpl implements DataExtractor {
    protected static final Map<String, Object> EMPTY_MAP = Collections.unmodifiableMap(new HashMap<String, Object>());

    protected ReportLoaderFactory loaderFactory;

    protected boolean putEmptyRowIfNoDataSelected = true;

    public DataExtractorImpl(ReportLoaderFactory loaderFactory) {
        Preconditions.checkNotNull(loaderFactory, "\"loaderFactory\" parameter can not be null");
        this.loaderFactory = loaderFactory;
    }

    public void extractData(Report report, Map<String, Object> params, BandData rootBand) {
        List<Map<String, Object>> rootBandData = getBandData(report.getRootBand(), null, params);
        if (CollectionUtils.isNotEmpty(rootBandData)) {
            rootBand.getData().putAll(rootBandData.get(0));
        }

        List<ReportBand> firstLevelBands = report.getRootBand().getChildren();
        if (firstLevelBands != null) {
            for (ReportBand definition : firstLevelBands) {
                List<BandData> bands = createBands(definition, rootBand, params);
                rootBand.addChildren(bands);
                rootBand.getFirstLevelBandDefinitionNames().add(definition.getName());
            }
        }
    }

    public void setPutEmptyRowIfNoDataSelected(boolean putEmptyRowIfNoDataSelected) {
        this.putEmptyRowIfNoDataSelected = putEmptyRowIfNoDataSelected;
    }

    public boolean getPutEmptyRowIfNoDataSelected() {
        return putEmptyRowIfNoDataSelected;
    }

    protected List<BandData> createBands(ReportBand definition, BandData parentBand, Map<String, Object> params) {
        List<Map<String, Object>> outputData = getBandData(definition, parentBand, params);
        return createBandsList(definition, parentBand, outputData, params);
    }

    protected List<BandData> createBandsList(ReportBand definition, BandData parentBand, List<Map<String, Object>> outputData, Map<String, Object> params) {
        List<BandData> bandsList = new ArrayList<BandData>();
        for (Map<String, Object> data : outputData) {
            BandData band = new BandData(definition.getName(), parentBand, definition.getBandOrientation());
            band.setData(data);
            Collection<ReportBand> childrenBandDefinitions = definition.getChildren();
            if (childrenBandDefinitions != null) {
                for (ReportBand childDefinition : childrenBandDefinitions) {
                    List<BandData> childBands = createBands(childDefinition, band, params);
                    band.addChildren(childBands);
                }
            }
            bandsList.add(band);
        }
        return bandsList;
    }

    protected List<Map<String, Object>> getBandData(ReportBand band, BandData parentBand, Map<String, Object> params) {
        Collection<ReportQuery> reportQueries = band.getReportQueries();
        if (CollectionUtils.isEmpty(reportQueries)) {
            return Collections.singletonList(params);
        }

        List<Map<String, Object>> result = null;
        if (!isEmptyBand(parentBand)) {
            result = getQueriesResult(band, parentBand, params, reportQueries);

            if (result != null) {
                //add input params to band
                for (Map<String, Object> map : result) {
                    map.putAll(params);
                }
            }
        }

        if (result == null) {
            result = Collections.emptyList();
        }

        if (getPutEmptyRowIfNoDataSelected() && CollectionUtils.isEmpty(result)) {
            result = new ArrayList<Map<String, Object>>();
            result.add(EMPTY_MAP);
        }

        return result;
    }

    protected List<Map<String, Object>> getQueriesResult(ReportBand band, BandData parentBand, Map<String, Object> params, Collection<ReportQuery> reportQueries) {
        List<Map<String, Object>> result;
        Iterator<ReportQuery> queryIterator = reportQueries.iterator();
        ReportQuery firstReportQuery = queryIterator.next();

        //gets data from first dataset
        result = getQueryData(parentBand, band, firstReportQuery, params);

        //adds data from second and following datasets to result
        while (queryIterator.hasNext()) {
            ReportQuery reportQuery = queryIterator.next();
            List<Map<String, Object>> currentQueryData = getQueryData(parentBand, band, reportQuery, params);
            String link = reportQuery.getLinkParameterName();
            if (StringUtils.isNotBlank(link)) {
                for (Map<String, Object> currentRow : currentQueryData) {
                    Object linkObj = currentRow.get(link);
                    if (linkObj != null) {
                        for (Map<String, Object> resultRow : result) {
                            Object linkObj2 = resultRow.get(link);
                            if (linkObj2 != null) {
                                if (linkObj.equals(linkObj2)) {
                                    resultRow.putAll(currentRow);
                                    break;
                                }
                            } else {
                                throw new DataLoadingException(String.format("An error occurred while loading data for band [%s]." +
                                        " Query defines link parameter [%s] but result does not contain such field. Query [%s].", band.getName(), link, firstReportQuery.getName()));
                            }
                        }
                    } else {
                        throw new DataLoadingException(String.format("An error occurred while loading data for band [%s]." +
                                " Query defines link parameter [%s] but result does not contain such field. Query [%s].", band.getName(), link, reportQuery.getName()));
                    }
                }
            } else {
                for (int j = 0; (j < result.size()) && (j < currentQueryData.size()); j++) {
                    result.get(j).putAll(currentQueryData.get(j));
                }
            }
        }

        return result;
    }

    protected boolean isEmptyBand(BandData parentBand) {
        return parentBand != null && parentBand.getData() == EMPTY_MAP;
    }

    protected List<Map<String, Object>> getQueryData(BandData parentBand, ReportBand band, ReportQuery reportQuery, Map<String, Object> paramsMap) {
        try {
            ReportDataLoader dataLoader = loaderFactory.createDataLoader(reportQuery.getLoaderType());
            return dataLoader.loadData(reportQuery, parentBand, paramsMap);
        } catch (ValidationException e) {
            throw e;
        } catch (Exception e) {
            throw new DataLoadingException(String.format("An error occurred while loading data for band [%s] and query [%s].", band.getName(), reportQuery.getName()), e);
        }
    }
}
TOP

Related Classes of com.haulmont.yarg.reporting.DataExtractorImpl

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.