package com.evolveum.midpoint.report.impl; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; import javax.xml.namespace.QName; import com.evolveum.midpoint.prism.Containerable; import com.evolveum.midpoint.prism.PrismContainerValue; import net.sf.jasperreports.engine.JRDataSource; import net.sf.jasperreports.engine.JRDataset; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JRParameter; import net.sf.jasperreports.engine.JRValueParameter; import net.sf.jasperreports.engine.JasperReportsContext; import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource; import net.sf.jasperreports.engine.query.JRAbstractQueryExecuter; import org.apache.commons.lang.StringUtils; import com.evolveum.midpoint.audit.api.AuditEventRecord; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.report.api.ReportService; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.util.exception.CommunicationException; import com.evolveum.midpoint.util.exception.ConfigurationException; import com.evolveum.midpoint.util.exception.ExpressionEvaluationException; import com.evolveum.midpoint.util.exception.ObjectNotFoundException; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.exception.SecurityViolationException; import com.evolveum.midpoint.util.exception.SystemException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; public abstract class MidPointQueryExecutor extends JRAbstractQueryExecuter{ private static final Trace LOGGER = TraceManager.getTrace(MidPointLocalQueryExecutor.class); private Object query; private String script; private Class type; private ReportService reportService; public String getScript() { return script; } public Object getQuery() { return query; } public Class getType() { return type; } protected Map<QName, Object> getParameters(){ JRParameter[] params = dataset.getParameters(); Map<QName, Object> expressionParameters = new HashMap<QName, Object>(); for (JRParameter param : params){ if (param.isSystemDefined()){ continue; } //LOGGER.trace(((JRBaseParameter)param).getName()); Object v = getParameterValue(param.getName()); try{ expressionParameters.put(new QName(param.getName()), new PrismPropertyValue(v)); } catch (Exception e){ //just skip properties that are not important for midpoint } LOGGER.trace("p.val: {}", v); } return expressionParameters; } protected Map<QName, Object> getPromptingParameters(){ JRParameter[] params = dataset.getParameters(); Map<QName, Object> expressionParameters = new HashMap<QName, Object>(); for (JRParameter param : params){ if (param.isSystemDefined()){ continue; } if (!param.isForPrompting()){ continue; } //LOGGER.trace(((JRBaseParameter)param).getName()); Object v = getParameterValue(param.getName()); try{ expressionParameters.put(new QName(param.getName()), new PrismPropertyValue(v)); } catch (Exception e){ //just skip properties that are not important for midpoint } LOGGER.trace("p.val: {}", v); } return expressionParameters; } protected abstract Object getParsedQuery(String query, Map<QName, Object> expressionParameters) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException; protected String getParsedScript(String script){ String normalized = script.replace("<code>", ""); return normalized.replace("</code>", ""); } protected MidPointQueryExecutor(JasperReportsContext jasperReportsContext, JRDataset dataset, Map<String, ? extends JRValueParameter> parametersMap) { super(jasperReportsContext, dataset, parametersMap); } protected abstract Collection<PrismObject<? extends ObjectType>> searchObjects(Object query, Collection<SelectorOptions<GetOperationOptions>> options) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException; protected abstract Collection<PrismContainerValue<? extends Containerable>> evaluateScript(String script, Map<QName, Object> parameters) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, ExpressionEvaluationException; protected abstract Collection<AuditEventRecord> searchAuditRecords(String script, Map<QName, Object> parameters) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException; protected abstract JRDataSource createDataSourceFromObjects(Collection<PrismObject<? extends ObjectType>> results); protected abstract JRDataSource createDataSourceFromContainerValues(Collection<PrismContainerValue<? extends Containerable>> results); @Override protected void parseQuery() { try { String s = dataset.getQuery().getText(); LOGGER.trace("query: " + s); if (StringUtils.isEmpty(s)) { query = null; } else { if (s.startsWith("<filter")) { query = getParsedQuery(s, getParameters()); // getParsedQuery(s, expressionParameters); } else if (s.startsWith("<code")) { script = getParsedScript(s); } } } catch (SchemaException | ObjectNotFoundException | ExpressionEvaluationException e) { // TODO Auto-generated catch block throw new SystemException(e.getMessage(), e); } } @Override public JRDataSource createDatasource() throws JRException { try { if (query == null && script == null){ throw new JRException("Neither query, nor script defined in the report."); } if (query != null) { Collection<PrismObject<? extends ObjectType>> results; results = searchObjects(query, SelectorOptions.createCollection(GetOperationOptions.createRaw())); return createDataSourceFromObjects(results); } else { if (script.contains("AuditEventRecord")){ Collection<AuditEventRecord> audtiEventRecords = searchAuditRecords(script, getPromptingParameters()); Collection<AuditEventRecordType> auditEventRecordsType = new ArrayList<>(); for (AuditEventRecord aer : audtiEventRecords){ AuditEventRecordType aerType = aer.createAuditEventRecordType(true); auditEventRecordsType.add(aerType); } return new JRBeanCollectionDataSource(auditEventRecordsType); } else { Collection<PrismContainerValue<? extends Containerable>> results; results = evaluateScript(script, getParameters()); return createDataSourceFromContainerValues(results); } } } catch (SchemaException | ObjectNotFoundException | SecurityViolationException | CommunicationException | ConfigurationException | ExpressionEvaluationException e) { // TODO Auto-generated catch block throw new JRException(e); } } @Override public void close() { // throw new UnsupportedOperationException("QueryExecutor.close() not supported"); //nothing to DO } @Override public boolean cancelQuery() throws JRException { throw new UnsupportedOperationException("QueryExecutor.cancelQuery() not supported"); } @Override protected String getParameterReplacement(String parameterName) { throw new UnsupportedOperationException("QueryExecutor.getParameterReplacement() not supported"); } }