Package reportgen.ren.executer

Source Code of reportgen.ren.executer.QueryExecuterSub

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package reportgen.ren.executer;

import java.util.ArrayList;
import java.util.List;
import org.jdom.Element;
import reportgen.utils.SupportXMLRootImpl;
import reportgen.prototype.queryresults.QueryResults;
import reportgen.prototype.queryresults.ResultsRow;
import reportgen.prototype.context.Context;
import reportgen.ren.loader.SubQueryLoaderResult;
import reportgen.ren.report.ReportQuery;
import reportgen.utils.ReportException;
import reportgen.prototype.utils.RowCount;
import reportgen.ren.report.column.ReportResultColumn;
import reportgen.ren.report.userinput.UserInputSelect;
import reportgen.prototype.utils.ItemSelectorEditable;
import reportgen.utils.Atom;
import reportgen.utils.SupportXMLRoot;
import reportgen.utils.XML;

/**
*
* @author axe
*/
public class QueryExecuterSub implements SupportXMLRoot {

    public static final String TAGNAME = "subreport";
    private static final String ATTR_QUERYID = "id";
    private static final String ATTR_TITLE = "selecttitle";
    private static final String ATTR_DESCRIPTION = "selectdescription";
    private static final String ATTR_SELECTCOLUMN = "col";
    private static final String ATTR_CONSTANT = "const";
    private static final String ATTR_CANBEOMMITED = "canBeOmitted";

    private static final int IGNORE_ROW = -1;

    /**
     * Название выбора, которую нужно отобразить пользователю при выборе строк.
     * (Выбирается пользователем при вставке подотчета в отчет)
     */
    private String selectTitle;

    /**
     * Описание выбора, которую нужно отобразить пользователю при выборе строк.
     * (Выбирается пользователем при вставке подотчета в отчет)
     */
    private String selectDescription;

    /**
     * Индекс колонки в результатах отчета, которую нужно отобразить
     * пользователю при выборе строк. (Выбирается пользователем при вставке
     * подотчета в отчет)
     */
    private int selectColumn;

    /**
     * РЕЖИМ СТРОК ВЫБОРКИ
     * Количество строк, которых нужно выбрать пользователю.
     */
    private RowCount rowCount;


    /**
     * Отчет будет выполнен при построении родительского отчета
     * и результаты будут сохранены
     */
    private boolean constant = false;

    private boolean canBeOmitted = false;
    private boolean isOmitted = false;

    /**
     * Должен ли пользователь выбрать результат отчета
     */
    private boolean needUserActivity = true;

    /**
     * Результаты запроса. Назначаются после выполнения ядра запроса и парсинга
     */
    private QueryResults queryResults;

    /**
     * Результаты запроса. Назначаются в момент составления отчета
     */
    private QueryResults defaultResults;

    /*
     * Строки, выбранные пользователем. Инициализируется при назначении результатов
     * отчета, при этом величина списка соответствует необходимому количеству строк
     * кторые должен выбрать пользователь. (в некоторых случаях пользователь может
     * выбрать иное количество строк)
     */
    private ArrayList<Integer> selectedRows;


    private final Atom atom;
    private final QueryExecuter report;

    /**
     * @param id табельный номер отчета
     * @param report ядро отчета
     * @param selectTitle название отчета
     * @param selectDescription описание отчета
     * @param selectColumn индекс колонки при выборе
     * @param activeRows активные строки отчета
     */
    public QueryExecuterSub(int id, ReportQuery report, String title, String description,
            String selectTitle, String selectDescription, int selectColumn, RowCount activeRows) {
        this.report = new QueryExecuter(id, report, title, description);
        this.selectTitle = selectTitle;
        this.selectDescription = selectDescription;
        this.selectColumn = selectColumn;
        this.rowCount = activeRows;
        this.atom = new Atom();
    }

     /**
     *
     * @param element
     * @param sl
     * @return
     * @throws reportgen.ren.exception.ReportException
     */
    public QueryExecuterSub(Element element, Context context) throws ReportException {
        assert element.getName().equals(TAGNAME);

        int reportId = XML.getIntAttribute(element, ATTR_QUERYID);
        SubQueryLoaderResult rpt = context.getQueryLoader().loadSubReport(reportId);
        report = new QueryExecuter(reportId, rpt.report, rpt.title, rpt.description);

        atom = new Atom(element, context);
        rowCount = new RowCount(element);
        selectTitle = XML.getStringAttribute(element, ATTR_TITLE);
        selectDescription = XML.getStringAttribute(element, ATTR_DESCRIPTION, "", false);

        String selectCol = SupportXMLRootImpl.getStringAttribute(element, ATTR_SELECTCOLUMN);
        selectColumn = -1;
        ItemSelectorEditable<ReportResultColumn> cols = report.getQuery().getColumns();
        for(int i=0; i<cols.size(); i++) {
            if(cols.get(i).getTitle().equals(selectCol)) {
                selectColumn = i;
            }
        }
        if(selectColumn == -1) {
            throw new ReportException("Неизвестная колонка выбора: " + selectCol);
        }

        constant = XML.getBoolAttribute(element, ATTR_CONSTANT, false, false);
        canBeOmitted = XML.getBoolAttribute(element, ATTR_CANBEOMMITED, false, false);

        Element resultsEl = element.getChild(QueryResults.TAG);
        if(resultsEl != null) {
            setDefaultResults(new QueryResults(resultsEl));
        } else if(constant) {
            throw new ReportException("Для подотчета '" + selectTitle + "' указано использовать"
                    + " предварительно загруженные результаты, но они отсутствуют");
        }
    }

    /**
     *
     * @return
     * @throws reportgen.ren.exception.ReportException
     */
    @Override
    public Element toXML() {
        Element element = new Element(TAGNAME);
        atom.toXML(element);
       
        element.setAttribute(ATTR_QUERYID, new Integer(report.getId()).toString());

        element.setAttribute(ATTR_TITLE, selectTitle);
        if(selectDescription.length() > 0) {
            element.setAttribute(ATTR_DESCRIPTION, selectDescription);
        }
        element.setAttribute(ATTR_SELECTCOLUMN, getColTitle(selectColumn));
        if(constant) {
            element.setAttribute(ATTR_CONSTANT, new Boolean(constant).toString());
        }
        if(canBeOmitted) {
            element.setAttribute(ATTR_CANBEOMMITED, new Boolean(canBeOmitted).toString());
        }
        rowCount.toXML(element);

        if(defaultResults != null) {
            element.addContent(defaultResults.toXML());
        }

        return element;
    }

    public QueryExecuter getReport() {
        return report;
    }

    public int getReportId() {
        return report.getId();
    }

    public String getReportTitle() {
        return report.getTitle();
    }


    public Atom getAtom() {
        return atom;
    }

    public boolean isCanBeOmitted() {
        return canBeOmitted;
    }

    public void setCanBeOmitted(boolean canBeOmitted) {
        this.canBeOmitted = canBeOmitted;
    }

    public boolean isOmitted() {
        return isOmitted;
    }

    /**
     *
     */
    public void clearDefaultResults() {
        defaultResults = null;
        constant = false;
    }

    /**
     *
     * @param count
     * @return
     */
    private static ArrayList<Integer> buildInitialSelection(int count) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        for(int i=0; i<count; i++) {
            list.add(i);
        }
        return list;
    }

    /**
     * @return the canBeSelected
     */
    public RowCount getActiveRows() {
        return rowCount;
    }

    /**
     * Назначается режим строк выборки, удаляет дефолтовые результаты.
     * @param canBeSelected the canBeSelected to set
     */
    public void setActiveRows(RowCount activeRows) {
        clearDefaultResults();
        this.rowCount = activeRows;
    }

    /**
     * @return the selectTitle
     */
    public String getSelectTitle() {
        return selectTitle;
    }

    /**
     * @param selectTitle the selectTitle to set
     */
    public void setSelectTitle(String selectTitle) {
        this.selectTitle = selectTitle;
    }

    /**
     * @return the selectDescription
     */
    public String getSelectDescription() {
        return selectDescription;
    }

    /**
     * @param selectDescription the selectDescription to set
     */
    public void setSelectDescription(String selectDescription) {
        this.selectDescription = selectDescription;
    }

    /**
     * @return the selectColumn
     */
    public int getSelectColumn() {
        return selectColumn;
    }

    public void setSelectColumn(int index) {
        this.selectColumn = index;
    }

    @Override
    public String toString() {
        return report.getTitle() + "(" + getSelectTitle() + ")";
    }

    public boolean isConstant() {
        return constant;
    }

    public void setConstant(boolean constant) throws ReportException {
        if(constant && defaultResults == null) {
            throw new ReportException("Не заданы дефолтовые значения");
        }
        this.constant = constant;
    }

    /**
     *
     * @param index
     * @return
     * @throws reportgen.ren.exception.ReportException
     */
    public Object getDefaultValue(int col) throws ReportException {
        return getDefaultColValue(col, IGNORE_ROW);
    }

    /**
     * @param index
     * @return
     * @throws reportgen.ren.exception.ReportException
     */
    private Object getDefaultColValue(int col, int row) throws ReportException {
        if(defaultResults == null || defaultResults.getRowCount() == 0) {
            throw new ReportException("Отсутствуют результаты выборки по-умолчанию");
        }
        //only specified row
        if(row != IGNORE_ROW ) {
            return defaultResults.getRow(row).getValue(col);
        }
        if(getActiveRows().isSingle()) {
            return defaultResults.getRow(0).getValue(col);
        }
        List set = new ArrayList();
        for(int i=0; i<defaultResults.getRowCount(); i++) {
            ResultsRow iRow = defaultResults.getRow(i);
            set.add(iRow.getValue(col));
        }
        return set;
    }


    /**
     * Назначение дефолтовых результатов для отчета.
     * Контролируется соответствие режиму строк подотчета
     * (назначаемому в панели списка подотчетов)
     * данные готовы для использования в отчете и поэтому должны соответствовать
     * критериям заданным в подотчете (количеству строк)
     * @param results
     * @param selectedRows
     * @throws reportgen.ren.exception.ReportException
     */
    public void setDefaultResults(QueryResults results)
            throws ReportException {
        assert results != null;

        if(results.getRowCount() == 0) {
            throw new ReportException("Нельзя назначать пустые результаты в качестве "
                    + "дефолтного значения подотчета '" + report.getTitle() + "'");
        }
        //дефолтные результаты должны соответствовать количеству строк подотчета
        if (rowCount.getMinimum() > results.getRowCount()) {
            throw new ReportException("Должно быть выбрано, не менее " + rowCount.getMinimum() + " строк(и)");
        }
        if (rowCount.getMaximum() < results.getRowCount()) {
            throw new ReportException("Должно быть выбрано, не более " + rowCount.getMaximum() + " строк(и)");
        }

        //назначаем результаты и отмечаем их как выброанные
        defaultResults = results;
        needUserActivity = false;
    }

    /**
     * Назначение результатов для отчета.
     * Проверка того, сколько строк вернул подотчет проверяется самим подотчетом
     * в момент парсинга результатов.
     * @param results
     */
    public void setResults(QueryResults results) throws ReportException {
        if(results.getRowCount() < rowCount.getMinimum()) {
            throw new ReportException(
                "Подотчет '" + report.getTitle() + "' вернул "+ results.getRowCount() + " строк(и),"
                + " а в условиях его использования предполагается выбрать "
                + " не менее " + rowCount.getMinimum() + "строк(и)");
        }
        this.queryResults = results;
       

        if(results.getRowCount() == 1 || rowCount.isAny()) {
            selectedRows = buildInitialSelection(results.getRowCount());
            needUserActivity = false;
    } else {
            needUserActivity = true;
            if(defaultResults == null) {
                selectedRows = null;
            } else {
                //попробуем выбрать дефолтные строки
                selectedRows = new ArrayList<Integer>();
                for(int i=0; i<defaultResults.getRowCount(); i++) {
                    Object iDefaultValue = defaultResults.getRow(i).getValue(selectColumn);
                    assert iDefaultValue != null : "iDefaultValue == null";

                    for(int j=0; j<queryResults.getRowCount(); j++) {
                        Object iRowValue = queryResults.getRow(j).getValue(selectColumn);
                        if(iRowValue != null
                                && iRowValue.equals(iDefaultValue)) {
                            selectedRows.add(j);
                            break;
                        }
                    }
                }
                if(selectedRows.size() == 0) {
                    selectedRows = null;
                }
            }
        }
    }


    /**
     *
     */
    public void clearResults() {
        this.queryResults = null;
        //очистка выбора пользователя
        selectedRows = null;
        needUserActivity = true;
    }


    /**
     * Возвращает объект - опция для выбора клиентом из списка.
     * Список - результат выполнения отчета.
     * @return null if report is constant and default values is present
     * @throws reportgen.ren.ReportException
     */
    UserInputSelect getResultInputValue() throws ReportException {
        if(isDefaultConstant() || !needUserActivity) {
            return null;
        }
        ArrayList<Object> options = new ArrayList<Object>();
        for(int i=0; i<queryResults.getRowCount(); i++) {
            ResultsRow row = queryResults.getRow(i);
            options.add(row.getValue(selectColumn));
        }

        return new UserInputSelect(new Integer(report.getId()).toString(),
                selectTitle, selectDescription, selectedRows, options, rowCount, canBeOmitted);
    }


    /**
     * После того как пользователь выбрал нужные опции из списка,
     * этой функцией они обновляются в отчете
     * Контролируется соответствие режиму строк отчета
     * @param ui
     * @throws reportgen.ren.ReportException
     */
    void setResultUserInput(UserInputSelect ui) throws ReportException {
        ArrayList<Integer> selected = ui.getSelected();
        if(selected.size() == 0) {
            if(!canBeOmitted) {
                throw new ReportException("Пользователь не сделал выбор");
            }
            isOmitted = true;
        } else {
            for(Integer index: selected) {
                if(index < 0 || index >= queryResults.getRowCount()) {
                    throw new ReportException("Пользователь сделал некорректный выбор");
                }
            }

            if(selected.size() > rowCount.getMaximum()) {
                throw new ReportException("Пользователь выбрал " + selected.size()
                        + " строк, а должен был выбрать не более" + rowCount.getMaximum());
            }

            if(selected.size() < rowCount.getMinimum()) {
                throw new ReportException("Пользователь выбрал " + selected.size()
                        + " строк, а должен был не менее " + rowCount.getMinimum());
            }

            selectedRows = selected;
            isOmitted = false;
        }
        needUserActivity = false;
    }


    /**
     *
     * @return
     */
    public boolean isResultsIsSet() {
        return queryResults != null;
    }


    public String getColTitle(int index) {
        ItemSelectorEditable<ReportResultColumn> cols = report.getQuery().getColumns();
        return cols.get(index).getTitle();
    }

    public String getColDesc(int index) {
        ItemSelectorEditable<ReportResultColumn> cols = report.getQuery().getColumns();
        return cols.get(index).getDescription();
    }

    /**
     * Возвращает класс столбца результата
     * @param index индекс столбца
     * @param forSingleRow true - рассматривать отчет построчно,
     *                     false -если рассматривать отчет как единое целое,
     * @return класс
     * @throws reportgen.exception.ReportException
     */
    public Class getColCls(int index, boolean forSingleRow) throws ReportException {
        ItemSelectorEditable<ReportResultColumn> cols = report.getQuery().getColumns();
        Class cls = cols.get(index).getCls();

        if(forSingleRow) {
            return cls;
        }

        if(rowCount.isSingle()) {
            return cls;
        }

        //неизвестное количество строк
        if(cls.equals(Long.class)) {
            List<Long> set = new ArrayList<Long>();
            return set.getClass();

        } else if(cls.equals(String.class)) {
            List<String> set = new ArrayList<String>();
            return set.getClass();
           
        }
        return List.class;
    }

    /**
     *
     * @return
     * @throws reportgen.exception.ReportException
     */
    public int getResultsRowCount() throws ReportException {
        if(isDefaultConstant()) {
            return defaultResults.getRowCount();
        }
        return queryResults.getRowCount();
    }

    public int getColumnCount() {
        return report.getQuery().getColumns().size();
    }



    public Object getColValue(int col) throws ReportException {
        if(isDefaultConstant()) {
            return getDefaultColValue(col, IGNORE_ROW);
        }
        return getResultsColValue(col, IGNORE_ROW);
    }

    /**
     *
     * @param index
     * @return
     * @throws reportgen.ren.exception.ReportException
     */
    public Object getColValue(int col, int row) throws ReportException {
        if(isDefaultConstant()) {
            return getDefaultColValue(col, row);
        }
        return getResultsColValue(col, row);
    }

    /**
     *
     * @param results
     * @param index
     * @return
     * @throws reportgen.ren.exception.ReportException
     */
    private Object getResultsColValue(int col, int row) throws ReportException {
        //ODZ
        if(isOmitted) {
            throw new ReportException("Пользователь не сделал свой выбор");
        }
        if(selectedRows == null || queryResults == null) {
            throw new ReportException("Подотчет '" + getSelectTitle
                    ()+ "(" + report.getTitle() +")' не выполнен, "
                    + "или пользователь еще сделал свой выбор");
        }

        //only specified row
        if(row != IGNORE_ROW ) {
            return queryResults.getRow(selectedRows.get(row)).getValue(col);
        }
        //only single row
        if(getActiveRows().isSingle()) {
            return queryResults.getRow(selectedRows.get(0)).getValue(col);
        }
        //several rows
        List set = new ArrayList();
        for(int i=0; i<selectedRows.size(); i++) {
            ResultsRow iRow = queryResults.getRow(selectedRows.get(i));
            set.add(iRow.getValue(col));
        }
        return set;
    }


    /**


    /**
      Возвращает список доступных колонок подотчета
     * @return
     */
    public List<SubReportColumn> getAvailiableColumns() {
        List<SubReportColumn> lst = new ArrayList<SubReportColumn>();
        ItemSelectorEditable<ReportResultColumn> cols = report.getQuery().getColumns();
        for(int i=0; i<cols.size(); i++) {
            lst.add(new SubReportColumn(this, i));
        }
        return lst;
    }


    /**
     * Возвращает индекс колонки по имени
     * @param column
     * @return
     */
    public int getColumnIndex(String column) throws ReportException {
        ItemSelectorEditable<ReportResultColumn> cols = report.getQuery().getColumns();
        for(int i=0; i<cols.size(); i++) {
            if(cols.get(i).getTitle().equals(column)) {
                return i;
            }
        }
        throw new ReportException("Колонка " + column + " в отчете "
                + report.getTitle() + " не найдена!");
    }

    private boolean isDefaultConstant() {
        return constant && defaultResults != null;
    }

    public boolean isDefaultValuesPresent() {
        return defaultResults != null;
    }
}
TOP

Related Classes of reportgen.ren.executer.QueryExecuterSub

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.