Package framework.beans.reportgen.item

Source Code of framework.beans.reportgen.item.ReportQueryBean

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

package framework.beans.reportgen.item;

import framework.audit.AuditDoc;
import framework.beans.EntityDetails;
import framework.beans.FacadeBean;
import framework.beans.directory.reportType.ReportType;
import framework.beans.reportgen.ReportEntitySetResource;
import framework.beans.security.BeanRights;
import framework.generic.ClipsServerException;
import framework.security.UserRightsSetAbstract;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.ejb.EJB;
import javax.ejb.Stateful;
import reportgen.prototype.queryresults.QueryResults;
import reportgen.ren.report.items.ResultColumnList;
import reportgen.prototype.utils.ItemSelectorEditable;
import reportgen.utils.ReportException;
import reportgen.ren.report.ReportQuery;
import reportgen.factory.ReportFactory;
import reportgen.ren.loader.SubQueryLoader;
import reportgen.ren.loader.SubQueryLoaderResult;
import reportgen.ren.executer.QueryExecuter;
import reportgen.ren.executer.QueryExecuterSub;
import reportgen.ren.executer.QueryResultsData;
import reportgen.prototype.Report;
import reportgen.ren.report.userinput.UserInputChunk;

/**
*
* @author petr
*/

@Stateful(mappedName="clips-beans/ReportQueryBean")
public class ReportQueryBean
        extends FacadeBean<ReportgenQuery>
        implements ReportQueryRemote, SubQueryLoader {

    public static int COMMAND_SET_COLLAB = 4;

    @EJB
    ReportEntitySetResource resource;
    private QueryExecuter rootQuery;

    public ReportQueryBean() {
        super(ReportgenQuery.class);
    }
   
    @Override
    protected void initBeanRights() throws ClipsServerException {
        resource.init();
        int[] r = new int[5];
       
        r[COMMAND_READ] = RightPresence(UserRightsSetAbstract.EXECUTE_REPORT.id);
        r[COMMAND_MODIFY] =  r[COMMAND_CREATE] = RightPresence(UserRightsSetAbstract.WRITE_REGION_ADMIN_DIRECTORY.id);
        r[COMMAND_REMOVE] = RightPresence(UserRightsSetAbstract.WRITE_REGION_ADMIN_DIRECTORY.id);
        r[COMMAND_SET_COLLAB] = RightPresence(UserRightsSetAbstract.WRITE_CLINIC_ADMIN_DIRECTORY.id);

        rights = new BeanRights(r);
    }


    /**
     * additionally checks, that in new edition of this reports, columns used in
     * another reports was not removed
     * @param entity
     * @param details
     * @throws framework.generic.ClipsServerException
     */
    @Override
    protected void onUpdate(ReportgenQuery entity,
            EntityDetails details, AuditDoc auditDoc, List<AuditDoc> auditDocList) throws ClipsServerException {
        QueryDetails d = (QueryDetails) details;
        if(d.query == null || d.query.length() == 0) {
            throw new ClipsServerException("Попытка сохранения пустого отчета");
        }
        if(d.title == null || d.title.length() > 255 || d.title.length() < 10) {
            throw new ClipsServerException("Название должно быть от 10 до 255 символов в длину");
        }
        if(d.description != null && d.description.length() > 1024) {
            throw new ClipsServerException("Описание должно быть не более 1024 символов в длину");
        }
        if (d.reportType == 0) {
            throw new ClipsServerException("Отчет не привязан ни к какой группе");
        }

        // check report
        Report report = null;
        try {
            report = ReportFactory.fromString(entity.getId(), d.query, this);
        } catch (ReportException ex) {
            throw new ClipsServerException("Попытка сохранения некорректного отчета", ex);
        }

        HashSet<String> newCols = new HashSet<String>();
        ResultColumnList newColsSelector = report.getColumns();
        for(int i=0; i<newColsSelector.size(); i++) {
            newCols.add(newColsSelector.get(i).getTitle());
        }

        //check super reports
        Field[] f = new Field[]{new Field("id", entity.getId(), Field.OPERATOR_NOT_EQUAL)};
        Iterator iterator = findEntityList(ReportgenQuery.class, f).iterator();
        while (iterator.hasNext()) {
            ReportgenQuery superReportQuery = (ReportgenQuery) iterator.next();
            ReportQuery superReport  = null;
            try {
                superReport = ReportFactory.fromString(superReportQuery.getId(),
                        superReportQuery.getQuery(), this);
            } catch (ReportException ex) {
                //do nothing
            }
            if(superReport == null) {
                continue;
            }
           
            Iterator<String> usedSubreportColumns = superReport.getUsedSubreportColumns(entity.getId()).iterator();
            while(usedSubreportColumns.hasNext()) {
                String col = usedSubreportColumns.next();
                if(!newCols.contains(col)) {
                    throw new ClipsServerException("Отчет '" + superReportQuery.getTitle()
                            + "' использует столбец данного отчета с именем '" + col
                            + "', который в новой редакции отсутствует.");
                }
            }
        }

        entity.setReportType(findEntity(ReportType.class, d.reportType));
        entity.setSubsidiary(d.subsidiary);
        entity.setQuery(d.query);
        entity.setTitle(d.title);
        entity.setDescription(d.description);
    }


    /**
     * checks all another reports in fact of using removing one
     * @param entity
     * @throws framework.generic.ClipsServerException
     */
    @Override
    protected void onRemove(ReportgenQuery entity,
            List<AuditDoc> audit) throws ClipsServerException {
               
        //check all other reports in fack of using removing one
        Field[] f = new Field[]{new Field("id", entity.getId(), Field.OPERATOR_NOT_EQUAL)};
        Iterator iterator = findEntityList(ReportgenQuery.class, f).iterator();
        while (iterator.hasNext()) {
            ReportgenQuery superReportQuery = (ReportgenQuery) iterator.next();
            ReportQuery superReport  = null;
            try {
                superReport = ReportFactory.fromString(superReportQuery.getId(),
                        superReportQuery.getQuery(), this);
            } catch (ReportException ex) {
                continue;
            }

            ItemSelectorEditable<QueryExecuterSub> usedSubreports = superReport.getSubReports();
            for(int i=0; i<usedSubreports.size(); i++) {
                QueryExecuterSub col = usedSubreports.get(i);
                if(col.getReportId() == entity.getId()) {
                    throw new ClipsServerException("Отчет '" + col.getReportTitle()
                            + "' не может быть удален, поскольку его использует отчет '"
                            + superReportQuery.getTitle() + "'");
                }
            }
        }

        //delete related objects
        deleteEntityList(ReportCollab.class, new Field [] { new Field("report", entity) });
        deleteEntityList(ReportQueryExecution.class, new Field [] { new Field("report", entity) });
    }


    @Override
    public List<QueryExecutionDetails> getExecutionDetails() throws ClipsServerException {
        checkCommandAccessibility(COMMAND_READ);

        List<ReportQueryExecution> list = findEntityList(ReportQueryExecution.class, "report", getExistentEntity());
        List<QueryExecutionDetails> res = new ArrayList<QueryExecutionDetails>(list.size());
        Iterator<ReportQueryExecution> it = list.iterator();
        while(it.hasNext()) {
            ReportQueryExecution data = it.next();
            res.add(data.getDetails());
        }

        return res;
    }

    /**
     * Возвращает сет ид коллабов, которым разрешено выполнять данный отчет
     * @param report ид отчета
     * @return
     * @throws framework.generic.ClipsServerException
     */
    @Override
    public Set<Integer> getCollabs() throws ClipsServerException {
        //checkCommandAccessibility(COMMAND_MODIFY);
        int report = getExistentEntity().getId();

        Iterator list = findEntityList(ReportCollab.class, "key.report", report).iterator();
        Set<Integer> res = new HashSet<Integer>();
        while(list.hasNext()) {
            ReportCollab reportCollab = (ReportCollab)list.next();
            res.add(reportCollab.getKey().getCollab());
        }

        return res;
    }

    /**
     * Назначает отчету сет ид коллабов, которым разрешено выполнять данный отчет
     * @param report ид репорта
     * @param collabs сет ид коллабов
     * @throws framework.generic.ClipsServerException
     */
    @Override
    public void setCollabs(Set<Integer> collabs) throws ClipsServerException {
        checkCommandAccessibility(COMMAND_SET_COLLAB);

        int report = getExistentEntity().getId();

        Set<Integer> backup = new HashSet<Integer>(collabs);
        Set<Integer> oldCollabs = getCollabs();

        collabs.removeAll(oldCollabs);

        oldCollabs.removeAll(backup);

        if(oldCollabs.size() > 0) {
            @SuppressWarnings("unchecked")

            Field f[] = {
                new Field("key.report", report),
                new Field("key.collab", oldCollabs, Field.OPERATOR_IN)
            };
            deleteEntityList(ReportCollab.class, f);
        }

        Iterator<Integer> addNew = collabs.iterator();
        while(addNew.hasNext()) {
            ReportCollab r = new ReportCollab();
            r.setKey(new ReportCollabPK(report, addNew.next()));
            System.out.println("Added new:" + r);
            manager.persist(r);
        }
    }

    private boolean canCollabToDo(int collabID) throws ClipsServerException {
        return getCollabs().contains(collabID);
    }

    @Override
    public Object doReport(String reportXML) throws ClipsServerException {
        checkCommandAccessibility(COMMAND_CREATE);
        Object rr = null;
        try {
            System.out.println("TESTING XML:\n" + reportXML);
            ReportQuery report = ReportFactory.fromString(0, reportXML, this);
            rootQuery = new QueryExecuter(0, report, "Тестовый отчет", "");
            rr = executeQuery(rootQuery);
        } catch (Exception reportException) {
            throw new ClipsServerException("При обработке отчета произошла ошибка", reportException);
        }

        return rr;
    }

    @Override
    public Object doReport(int id) throws ClipsServerException {
        if(!canCollabToDo(getCollaboratorId())) {
            checkCommandAccessibility(COMMAND_READ);
        }
        ReportgenQuery query = findEntity(ReportgenQuery.class, id);
        try {
            ReportQuery report = ReportFactory.fromString(id, query.getQuery(), this);
            rootQuery = new QueryExecuter(id, report, query.getTitle(), query.getDescription());
            return executeQuery(rootQuery);
        } catch (Exception reportException) {
            throw new ClipsServerException("При обработке отчета произошла ошибка", reportException);
        }
    }

    @Override
    public Object continueReport(UserInputChunk input) throws ClipsServerException {
        if(!canCollabToDo(getCollaboratorId())) {
            checkCommandAccessibility(COMMAND_READ);
        }
        if(rootQuery == null) {
            throw new ClipsServerException("Некорректная попытка продолжить выполнение отчета");
        }
        try {
            if(input != null) {
                setInput(rootQuery, input);
            }
            return executeQuery(rootQuery);
        } catch (ReportException reportException) {
            throw new ClipsServerException("При обработке отчета произошла ошибка", reportException);
        }
    }

    /**
     * Выполняет первый по приоритету, нуждающийся в выполнении
     * @param parentQuery
     * @return
     * @throws reportgen.ren.ReportException
     */
    private Object executeQuery(QueryExecuter query)
            throws ReportException {

        //проверим, что все подотчеты рассчитаны
        ItemSelectorEditable<QueryExecuterSub> subreports = query.getQuery().getSubReports();
        for(int i=0; i<subreports.size(); i++) {
            QueryExecuterSub subquery = subreports.get(i);
            if(subquery.isConstant() || subquery.isResultsIsSet()) {
                //не трогать отчет, который является константой или уже рассчитан
                continue;
            }
            //РЕКУРСИВНО рассчитываем подотчет
            Object result = executeQuery(subquery.getReport());
            if(result instanceof  QueryResults) {
                QueryResults queryResults = (QueryResults) result;
                subquery.setResults(queryResults);
                result = new QueryResultsData(query.getId(), subquery, queryResults);
            }
            //либо подотчет рассчитан, и вернем данные об этом клиенту
            // либо требуется пользовательский ввод
            return result;
        }

        //все подотчет рассчитаны, build input data if user selection need
        UserInputChunk inputNeed = query.getInputValue();
        if(inputNeed != null) {
            return inputNeed;
        }

        //now ready for executing - execute
        return query.execute(manager);
    }


    /**
     * Назначает входное значение одному из отчетов. Данный отчет и все
     * отчеты следующие по приоритету подвергаются очистке результатов.
     * @param query
     * @param input
     * @return
     * @throws ReportException
     */
    private boolean setInput(QueryExecuter query, UserInputChunk input)
            throws ReportException {
        boolean inputUsed = (input == null);

        if(input != null  && input.getId() == query.getId()) {
            query.setUserInput(input);
            return true;
        }

        ItemSelectorEditable<QueryExecuterSub> subreports = query.getQuery().getSubReports();
        for(int i=0; i<subreports.size(); i++) {
            QueryExecuterSub subquery = subreports.get(i);
            if(subquery.isConstant()) {
                //не трогать отчет, который является константой
                continue;
            }

            if(!inputUsed) {
                inputUsed = setInput(subquery.getReport(), input);
            } else {
                // для всех последующих отчетов, кроме данного, корректровать
                // ввод пользователя не обязательно
                // (флаг корректируется при назначении результатов отчета)
                //subquery.getReport().setUserInputIsDone(false);
            }

            if(inputUsed) {
                //для всех последующих отчетов, включая данный, очищаем результаты расчета
                subquery.clearResults();
            }
        }
        return inputUsed;
    }



    /**
     * Возвращает подотчет.
     * Используется сервером. проверка прав не требуется.
     * @param id
     * @return
     * @throws reportgen.ren.ReportException
     */
    @Override
    public SubQueryLoaderResult loadSubReport(int id) throws ReportException {
        ReportgenQuery query = manager.find(ReportgenQuery.class, id);
        if(query == null) {
            throw new ReportException("Запроса с номером " + id + " не существует!");
        }

        SubQueryLoaderResult res = new SubQueryLoaderResult();
        res.title = query.getTitle();
        res.description = query.getDescription();
        res.report = ReportFactory.fromString(id, query.getQuery(), this);
        return res;
    }
}
TOP

Related Classes of framework.beans.reportgen.item.ReportQueryBean

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.