diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/box/InfoBoxPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/box/InfoBoxPanel.java index 3a1970d28ed..1e1d2a0b307 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/box/InfoBoxPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/box/InfoBoxPanel.java @@ -37,8 +37,10 @@ import com.evolveum.midpoint.gui.api.page.PageBase; import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; +import com.evolveum.midpoint.model.api.DashboardWidget; import com.evolveum.midpoint.model.api.authentication.CompiledObjectCollectionView; import com.evolveum.midpoint.model.api.context.EvaluatedPolicyRule; +import com.evolveum.midpoint.model.api.util.DashboardUtils; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.query.ObjectQuery; @@ -60,8 +62,12 @@ import com.evolveum.midpoint.web.page.admin.reports.dto.AuditEventRecordProvider; import com.evolveum.midpoint.web.page.admin.reports.dto.AuditSearchDto; import com.evolveum.midpoint.web.page.admin.resources.PageResources; +import com.evolveum.midpoint.web.page.admin.roles.PageRoles; import com.evolveum.midpoint.web.page.admin.server.PageTaskEdit; import com.evolveum.midpoint.web.page.admin.server.PageTasks; +import com.evolveum.midpoint.web.page.admin.services.PageServices; +import com.evolveum.midpoint.web.page.admin.users.PageOrgTree; +import com.evolveum.midpoint.web.page.admin.users.PageUsers; import com.evolveum.midpoint.web.util.OnePageParameterEncoder; import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordItemType; import com.evolveum.midpoint.xml.ns._public.common.common_3.AuditSearchType; @@ -76,8 +82,12 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectCollectionType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ServiceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType; /** @@ -100,7 +110,7 @@ public abstract class InfoBoxPanel extends Panel{ private static final String NUMBER_MESSAGE_UNKNOWN = "InfoBoxPanel.message.unknown"; public static final String VAR_PROPORTIONAL = "proportional"; - private static final String VAR_POLICY_SITUATIONS = "policySituations"; +// private static final String VAR_POLICY_SITUATIONS = "policySituations"; private static HashMap> linksRefCollections; private static HashMap> linksRefObjects; @@ -113,11 +123,13 @@ public abstract class InfoBoxPanel extends Panel{ put(ResourceType.COMPLEX_TYPE.getLocalPart(), PageResources.class); put(AuditEventRecordItemType.COMPLEX_TYPE.getLocalPart(), PageAuditLogViewer.class); put(TaskType.COMPLEX_TYPE.getLocalPart(), PageTasks.class); + put(UserType.COMPLEX_TYPE.getLocalPart(), PageUsers.class); + put(RoleType.COMPLEX_TYPE.getLocalPart(), PageRoles.class); + put(OrgType.COMPLEX_TYPE.getLocalPart(), PageOrgTree.class); + put(ServiceType.COMPLEX_TYPE.getLocalPart(), PageServices.class); } }; - } - - static { + linksRefObjects = new HashMap>() { private static final long serialVersionUID = 1L; @@ -129,7 +141,7 @@ public abstract class InfoBoxPanel extends Panel{ private static PageBase pageBase; private DisplayType display; - private DisplayType variationDisplay; +// private DisplayType variationDisplay; public InfoBoxPanel(String id, IModel model, PageBase pageBase) { super(id, model); @@ -147,22 +159,37 @@ protected void onInitialize() { } private void initLayout() { - IModel model = (IModel)getDefaultModel(); + IModel data = new IModel() { + private static final long serialVersionUID = 1L; + + @Override + public DashboardWidget getObject() { + DashboardWidget ret = DashboardUtils.createWidgetData(model.getObject(), getPageBase().getModelService(), + getPageBase().getTaskManager(), getPageBase().getExpressionFactory(), getPageBase().getAuditService(), + getPageBase().getClock(), getPageBase().getModelInteractionService()); + setDisplay(ret.getDisplay()); + return ret; + } + }; + this.display = model.getObject().getDisplay(); WebMarkupContainer infoBox = new WebMarkupContainer(ID_INFO_BOX); add(infoBox); - Label number = new Label(ID_NUMBER, getNumberMessage()); //number message have to add before icon because is needed evaluate variation + Label number = new Label(ID_NUMBER, + data.getObject().getNumberMessage() == null ? + getPageBase().createStringResource(NUMBER_MESSAGE_UNKNOWN) : + getStringModel(data.getObject().getNumberMessage())); //number message have to add before icon because is needed evaluate variation infoBox.add(number); - DisplayType combinatedDisplay = combinateDisplay(); IModel displayModel = new IModel() { - + private static final long serialVersionUID = 1L; + @Override public DisplayType getObject() { - return combinatedDisplay; + return display; } }; @@ -194,70 +221,74 @@ public DisplayType getObject() { customInitLayout(infoBox); } - private DisplayType combinateDisplay() { - DisplayType combinatedDisplay = new DisplayType(); - if (variationDisplay == null) { - return display; - } - if(StringUtils.isBlank(variationDisplay.getColor())) { - combinatedDisplay.setColor(display.getColor()); - } else { - combinatedDisplay.setColor(variationDisplay.getColor()); - } - if(StringUtils.isBlank(variationDisplay.getCssClass())) { - combinatedDisplay.setCssClass(display.getCssClass()); - } else { - combinatedDisplay.setCssClass(variationDisplay.getCssClass()); - } - if(StringUtils.isBlank(variationDisplay.getCssStyle())) { - combinatedDisplay.setCssStyle(display.getCssStyle()); - } else { - combinatedDisplay.setCssStyle(variationDisplay.getCssStyle()); - } - if(variationDisplay.getHelp() == null) { - combinatedDisplay.setHelp(display.getHelp()); - } else { - combinatedDisplay.setHelp(variationDisplay.getHelp()); - } - if(variationDisplay.getLabel() == null) { - combinatedDisplay.setLabel(display.getLabel()); - } else { - combinatedDisplay.setLabel(variationDisplay.getLabel()); - } - if(variationDisplay.getPluralLabel() == null) { - combinatedDisplay.setPluralLabel(display.getPluralLabel()); - } else { - combinatedDisplay.setPluralLabel(variationDisplay.getPluralLabel()); - } - if(variationDisplay.getTooltip() == null) { - combinatedDisplay.setTooltip(display.getTooltip()); - } else { - combinatedDisplay.setTooltip(variationDisplay.getTooltip()); - } - if(variationDisplay.getIcon() == null) { - combinatedDisplay.setIcon(display.getIcon()); - } else if(display.getIcon() != null){ - IconType icon = new IconType(); - if(StringUtils.isBlank(variationDisplay.getIcon().getCssClass())) { - icon.setCssClass(display.getIcon().getCssClass()); - } else { - icon.setCssClass(variationDisplay.getIcon().getCssClass()); - } - if(StringUtils.isBlank(variationDisplay.getIcon().getColor())) { - icon.setColor(display.getIcon().getColor()); - } else { - icon.setColor(variationDisplay.getIcon().getColor()); - } - if(StringUtils.isBlank(variationDisplay.getIcon().getImageUrl())) { - icon.setImageUrl(display.getIcon().getImageUrl()); - } else { - icon.setImageUrl(variationDisplay.getIcon().getImageUrl()); - } - combinatedDisplay.setIcon(icon); - } - - return combinatedDisplay; + public void setDisplay(DisplayType display) { + this.display = display; } + +// private DisplayType combinateDisplay() { +// DisplayType combinatedDisplay = new DisplayType(); +// if (variationDisplay == null) { +// return display; +// } +// if(StringUtils.isBlank(variationDisplay.getColor())) { +// combinatedDisplay.setColor(display.getColor()); +// } else { +// combinatedDisplay.setColor(variationDisplay.getColor()); +// } +// if(StringUtils.isBlank(variationDisplay.getCssClass())) { +// combinatedDisplay.setCssClass(display.getCssClass()); +// } else { +// combinatedDisplay.setCssClass(variationDisplay.getCssClass()); +// } +// if(StringUtils.isBlank(variationDisplay.getCssStyle())) { +// combinatedDisplay.setCssStyle(display.getCssStyle()); +// } else { +// combinatedDisplay.setCssStyle(variationDisplay.getCssStyle()); +// } +// if(variationDisplay.getHelp() == null) { +// combinatedDisplay.setHelp(display.getHelp()); +// } else { +// combinatedDisplay.setHelp(variationDisplay.getHelp()); +// } +// if(variationDisplay.getLabel() == null) { +// combinatedDisplay.setLabel(display.getLabel()); +// } else { +// combinatedDisplay.setLabel(variationDisplay.getLabel()); +// } +// if(variationDisplay.getPluralLabel() == null) { +// combinatedDisplay.setPluralLabel(display.getPluralLabel()); +// } else { +// combinatedDisplay.setPluralLabel(variationDisplay.getPluralLabel()); +// } +// if(variationDisplay.getTooltip() == null) { +// combinatedDisplay.setTooltip(display.getTooltip()); +// } else { +// combinatedDisplay.setTooltip(variationDisplay.getTooltip()); +// } +// if(variationDisplay.getIcon() == null) { +// combinatedDisplay.setIcon(display.getIcon()); +// } else if(display.getIcon() != null){ +// IconType icon = new IconType(); +// if(StringUtils.isBlank(variationDisplay.getIcon().getCssClass())) { +// icon.setCssClass(display.getIcon().getCssClass()); +// } else { +// icon.setCssClass(variationDisplay.getIcon().getCssClass()); +// } +// if(StringUtils.isBlank(variationDisplay.getIcon().getColor())) { +// icon.setColor(display.getIcon().getColor()); +// } else { +// icon.setColor(variationDisplay.getIcon().getColor()); +// } +// if(StringUtils.isBlank(variationDisplay.getIcon().getImageUrl())) { +// icon.setImageUrl(display.getIcon().getImageUrl()); +// } else { +// icon.setImageUrl(variationDisplay.getIcon().getImageUrl()); +// } +// combinatedDisplay.setIcon(icon); +// } +// +// return combinatedDisplay; +// } private DashboardWidgetSourceTypeType getSourceType(IModel model) { if(isSourceTypeOfDataNull(model)) { @@ -266,262 +297,262 @@ private DashboardWidgetSourceTypeType getSourceType(IModel return model.getObject().getData().getSourceType(); } - private IModel getNumberMessage() { - IModel model = (IModel)getDefaultModel(); - DashboardWidgetSourceTypeType sourceType = getSourceType(model); - DashboardWidgetPresentationType presentation = model.getObject().getPresentation(); - switch (sourceType) { - case OBJECT_COLLECTION: - if(!isDataFieldsOfPresentationNullOrEmpty(presentation)) { - return generateNumberMessageForCollection(presentation); - } - break; - case AUDIT_SEARCH: - if(!isDataFieldsOfPresentationNullOrEmpty(presentation)) { - return generateNumberMessageForAuditSearch(presentation); - } - break; - case OBJECT: - if(!isDataFieldsOfPresentationNullOrEmpty(presentation)) { - return generateNumberMessageForObject(presentation); - } - break; - } - return getPageBase().createStringResource(NUMBER_MESSAGE_UNKNOWN); - } +// private IModel getNumberMessage() { +// IModel model = (IModel)getDefaultModel(); +// DashboardWidgetSourceTypeType sourceType = getSourceType(model); +// DashboardWidgetPresentationType presentation = model.getObject().getPresentation(); +// switch (sourceType) { +// case OBJECT_COLLECTION: +// if(!isDataFieldsOfPresentationNullOrEmpty(presentation)) { +// return generateNumberMessageForCollection(presentation); +// } +// break; +// case AUDIT_SEARCH: +// if(!isDataFieldsOfPresentationNullOrEmpty(presentation)) { +// return generateNumberMessageForAuditSearch(presentation); +// } +// break; +// case OBJECT: +// if(!isDataFieldsOfPresentationNullOrEmpty(presentation)) { +// return generateNumberMessageForObject(presentation); +// } +// break; +// } +// return getPageBase().createStringResource(NUMBER_MESSAGE_UNKNOWN); +// } - private boolean isDataFieldsOfPresentationNullOrEmpty(DashboardWidgetPresentationType presentation) { - if(presentation != null) { - if(presentation.getDataField() != null) { - if(!presentation.getDataField().isEmpty()) { - return false; - } else { - LOGGER.error("DataField of presentation is empty"); - } - } else { - LOGGER.error("DataField of presentation is not defined"); - } - } else { - LOGGER.error("Presentation of widget is not defined"); - } - - return true; - } +// private boolean isDataFieldsOfPresentationNullOrEmpty(DashboardWidgetPresentationType presentation) { +// if(presentation != null) { +// if(presentation.getDataField() != null) { +// if(!presentation.getDataField().isEmpty()) { +// return false; +// } else { +// LOGGER.error("DataField of presentation is empty"); +// } +// } else { +// LOGGER.error("DataField of presentation is not defined"); +// } +// } else { +// LOGGER.error("Presentation of widget is not defined"); +// } +// +// return true; +// } - private IModel generateNumberMessageForObject(DashboardWidgetPresentationType dashboardWidgetPresentationType) { - ObjectType object = getObjectFromObjectRef(); - if(object == null) { - return getPageBase().createStringResource(NUMBER_MESSAGE_UNKNOWN); - } - return generateNumberMessage(dashboardWidgetPresentationType, createVariables(object.asPrismObject(), null, null)); - } +// private IModel generateNumberMessageForObject(DashboardWidgetPresentationType dashboardWidgetPresentationType) { +// ObjectType object = getObjectFromObjectRef(); +// if(object == null) { +// return getPageBase().createStringResource(NUMBER_MESSAGE_UNKNOWN); +// } +// return generateNumberMessage(dashboardWidgetPresentationType, createVariables(object.asPrismObject(), null, null)); +// } - private IModel generateNumberMessageForAuditSearch(DashboardWidgetPresentationType dashboardWidgetPresentationType) { - ObjectCollectionType collection = getObjectCollectionType(); - if(collection == null) { - return getPageBase().createStringResource(NUMBER_MESSAGE_UNKNOWN); - } - AuditSearchType auditSearch = collection.getAuditSearch(); - if(auditSearch == null) { - LOGGER.error("AuditSearch of ObjectCollection is not found in widget " + - ((IModel)getDefaultModel()).getObject().getIdentifier()); - return getPageBase().createStringResource(NUMBER_MESSAGE_UNKNOWN); - } - if(auditSearch.getRecordQuery() == null) { - LOGGER.error("RecordQuery of auditSearch is not defined in widget " + - ((IModel)getDefaultModel()).getObject().getIdentifier()); - return getPageBase().createStringResource(NUMBER_MESSAGE_UNKNOWN); - } - - Map parameters = new HashMap(); - String query = getQueryForCount(AuditEventRecordProvider.createQuery(collection, - parameters, false, getPageBase().getClock())); - LOGGER.debug("Parameters for select: " + parameters); - int value = (int) getPageBase().getAuditService().countObjects( - query, parameters); - Integer domainValue = null; - if(auditSearch.getDomainQuery() == null) { - LOGGER.error("DomainQuery of auditSearch is not defined"); - } else { - parameters = new HashMap(); - query = getQueryForCount(AuditEventRecordProvider.createQuery(collection, - parameters, true, getPageBase().getClock())); - LOGGER.debug("Parameters for select: " + parameters); - domainValue = (int) getPageBase().getAuditService().countObjects( - query, parameters); - } - LOGGER.debug("Value: {}, Domain value: {}", value, domainValue); - IntegerStatType statType = generateIntegerStat(value, domainValue); - return generateNumberMessage(dashboardWidgetPresentationType, createVariables(null, statType, null)); - } +// private IModel generateNumberMessageForAuditSearch(DashboardWidgetPresentationType dashboardWidgetPresentationType) { +// ObjectCollectionType collection = getObjectCollectionType(); +// if(collection == null) { +// return getPageBase().createStringResource(NUMBER_MESSAGE_UNKNOWN); +// } +// AuditSearchType auditSearch = collection.getAuditSearch(); +// if(auditSearch == null) { +// LOGGER.error("AuditSearch of ObjectCollection is not found in widget " + +// ((IModel)getDefaultModel()).getObject().getIdentifier()); +// return getPageBase().createStringResource(NUMBER_MESSAGE_UNKNOWN); +// } +// if(auditSearch.getRecordQuery() == null) { +// LOGGER.error("RecordQuery of auditSearch is not defined in widget " + +// ((IModel)getDefaultModel()).getObject().getIdentifier()); +// return getPageBase().createStringResource(NUMBER_MESSAGE_UNKNOWN); +// } +// +// Map parameters = new HashMap(); +// String query = getQueryForCount(AuditEventRecordProvider.createQuery(collection, +// parameters, false, getPageBase().getClock())); +// LOGGER.debug("Parameters for select: " + parameters); +// int value = (int) getPageBase().getAuditService().countObjects( +// query, parameters); +// Integer domainValue = null; +// if(auditSearch.getDomainQuery() == null) { +// LOGGER.error("DomainQuery of auditSearch is not defined"); +// } else { +// parameters = new HashMap(); +// query = getQueryForCount(AuditEventRecordProvider.createQuery(collection, +// parameters, true, getPageBase().getClock())); +// LOGGER.debug("Parameters for select: " + parameters); +// domainValue = (int) getPageBase().getAuditService().countObjects( +// query, parameters); +// } +// LOGGER.debug("Value: {}, Domain value: {}", value, domainValue); +// IntegerStatType statType = generateIntegerStat(value, domainValue); +// return generateNumberMessage(dashboardWidgetPresentationType, createVariables(null, statType, null)); +// } - private String getQueryForCount(String query) { - query = "select count (*) " + query; - query = query.split("order")[0]; - LOGGER.debug("Query for select: " + query); - return query; - } +// private String getQueryForCount(String query) { +// query = "select count (*) " + query; +// query = query.split("order")[0]; +// LOGGER.debug("Query for select: " + query); +// return query; +// } - private IModel generateNumberMessageForCollection(DashboardWidgetPresentationType dashboardWidgetPresentationType) { - ObjectCollectionType valueCollection = getObjectCollectionType(); - IModel model = (IModel)getDefaultModel(); - if(valueCollection != null && valueCollection.getType() != null && valueCollection.getType().getLocalPart() != null) { - int value = getObjectCount(valueCollection, true); - - int domainValue; - if( valueCollection.getDomain() != null && valueCollection.getDomain().getCollectionRef() != null) { - ObjectReferenceType ref = valueCollection.getDomain().getCollectionRef(); - Task task = getPageBase().createSimpleTask("Search domain collection"); - ObjectCollectionType domainCollection = (ObjectCollectionType)WebModelServiceUtils.loadObject(ref, - getPageBase(), task, task.getResult()).getRealValue(); - domainValue = getObjectCount(domainCollection, true); - } else { - LOGGER.error("Domain or collectionRef in domain is null in collection " + valueCollection.toString()); - LOGGER.trace("Using filter for all object based on type"); - domainValue = getObjectCount(valueCollection, false); - } - IntegerStatType statType = generateIntegerStat(value, domainValue); - - Task task = getPageBase().createSimpleTask("Evaluate collection"); - try { - CompiledObjectCollectionView compiledCollection = getPageBase().getModelInteractionService().compileObjectCollectionView( - valueCollection.asPrismObject(), null, task, task.getResult()); - Collection evalPolicyRules = getPageBase().getModelInteractionService().evaluateCollectionPolicyRules( - valueCollection.asPrismObject(), compiledCollection, null, task, task.getResult()); - Collection policySituations = new ArrayList(); - for(EvaluatedPolicyRule evalPolicyRule : evalPolicyRules) { - if(!evalPolicyRule.getAllTriggers().isEmpty()) { - policySituations.add(evalPolicyRule.getPolicySituation()); - } - } - return generateNumberMessage(dashboardWidgetPresentationType, createVariables(null, statType, policySituations)); - } catch (Exception e) { - LOGGER.error(e.getMessage(), e); - return getPageBase().createStringResource(NUMBER_MESSAGE_UNKNOWN); - } - - } else { - LOGGER.error("CollectionType from collectionRef is null in widget " + model.getObject().getIdentifier()); - } - return getPageBase().createStringResource(NUMBER_MESSAGE_UNKNOWN); - } +// private IModel generateNumberMessageForCollection(DashboardWidgetPresentationType dashboardWidgetPresentationType) { +// ObjectCollectionType valueCollection = getObjectCollectionType(); +// IModel model = (IModel)getDefaultModel(); +// if(valueCollection != null && valueCollection.getType() != null && valueCollection.getType().getLocalPart() != null) { +// int value = getObjectCount(valueCollection, true); +// +// int domainValue; +// if( valueCollection.getDomain() != null && valueCollection.getDomain().getCollectionRef() != null) { +// ObjectReferenceType ref = valueCollection.getDomain().getCollectionRef(); +// Task task = getPageBase().createSimpleTask("Search domain collection"); +// ObjectCollectionType domainCollection = (ObjectCollectionType)WebModelServiceUtils.loadObject(ref, +// getPageBase(), task, task.getResult()).getRealValue(); +// domainValue = getObjectCount(domainCollection, true); +// } else { +// LOGGER.error("Domain or collectionRef in domain is null in collection " + valueCollection.toString()); +// LOGGER.trace("Using filter for all object based on type"); +// domainValue = getObjectCount(valueCollection, false); +// } +// IntegerStatType statType = generateIntegerStat(value, domainValue); +// +// Task task = getPageBase().createSimpleTask("Evaluate collection"); +// try { +// CompiledObjectCollectionView compiledCollection = getPageBase().getModelInteractionService().compileObjectCollectionView( +// valueCollection.asPrismObject(), null, task, task.getResult()); +// Collection evalPolicyRules = getPageBase().getModelInteractionService().evaluateCollectionPolicyRules( +// valueCollection.asPrismObject(), compiledCollection, null, task, task.getResult()); +// Collection policySituations = new ArrayList(); +// for(EvaluatedPolicyRule evalPolicyRule : evalPolicyRules) { +// if(!evalPolicyRule.getAllTriggers().isEmpty()) { +// policySituations.add(evalPolicyRule.getPolicySituation()); +// } +// } +// return generateNumberMessage(dashboardWidgetPresentationType, createVariables(null, statType, policySituations)); +// } catch (Exception e) { +// LOGGER.error(e.getMessage(), e); +// return getPageBase().createStringResource(NUMBER_MESSAGE_UNKNOWN); +// } +// +// } else { +// LOGGER.error("CollectionType from collectionRef is null in widget " + model.getObject().getIdentifier()); +// } +// return getPageBase().createStringResource(NUMBER_MESSAGE_UNKNOWN); +// } - private ExpressionVariables createVariables(PrismObject object, IntegerStatType statType, Collection policySituations) { - ExpressionVariables variables = new ExpressionVariables(); - if(statType != null || policySituations != null) { - VariablesMap variablesMap = new VariablesMap(); - if(statType != null ) { - variablesMap.put(ExpressionConstants.VAR_INPUT, statType, statType.getClass()); - variablesMap.put(VAR_PROPORTIONAL, statType, statType.getClass()); - } - if(policySituations != null) { - variablesMap.put(VAR_POLICY_SITUATIONS, policySituations, EvaluatedPolicyRule.class); - } - variables.addVariableDefinitions(variablesMap ); - } - if(object != null) { - variables.addVariableDefinition(ExpressionConstants.VAR_OBJECT, object, object.getDefinition()); - } - - return variables; - } +// private ExpressionVariables createVariables(PrismObject object, IntegerStatType statType, Collection policySituations) { +// ExpressionVariables variables = new ExpressionVariables(); +// if(statType != null || policySituations != null) { +// VariablesMap variablesMap = new VariablesMap(); +// if(statType != null ) { +// variablesMap.put(ExpressionConstants.VAR_INPUT, statType, statType.getClass()); +// variablesMap.put(VAR_PROPORTIONAL, statType, statType.getClass()); +// } +// if(policySituations != null) { +// variablesMap.put(VAR_POLICY_SITUATIONS, policySituations, EvaluatedPolicyRule.class); +// } +// variables.addVariableDefinitions(variablesMap ); +// } +// if(object != null) { +// variables.addVariableDefinition(ExpressionConstants.VAR_OBJECT, object, object.getDefinition()); +// } +// +// return variables; +// } - private IntegerStatType generateIntegerStat(Integer value, Integer domainValue){ - IntegerStatType statType = new IntegerStatType(); - statType.setValue(value); - statType.setDomain(domainValue); - return statType; - } +// private IntegerStatType generateIntegerStat(Integer value, Integer domainValue){ +// IntegerStatType statType = new IntegerStatType(); +// statType.setValue(value); +// statType.setDomain(domainValue); +// return statType; +// } - private IModel generateNumberMessage(DashboardWidgetPresentationType dashboardWidgetPresentationType, ExpressionVariables variables) { - IModel model = (IModel)getDefaultModel(); - Map numberMessagesParts = new HashMap(); - model.getObject().getPresentation().getDataField().forEach(dataField -> { - switch(dataField.getFieldType()) { - - case VALUE: - Task task = getPageBase().createSimpleTask("Search domain collection"); - try { - String valueMessage = getStringExpressionMessage(variables, task, task.getResult(), - dataField.getExpression(), "Get value message"); - if(valueMessage == null) { - valueMessage = getPageBase().createStringResource(NUMBER_MESSAGE_UNKNOWN).toString(); - } - numberMessagesParts.put(DashboardWidgetDataFieldTypeType.VALUE, valueMessage); - } catch (Exception e) { - LOGGER.error(e.getMessage(), e); - } - break; - - case UNIT: - task = getPageBase().createSimpleTask("Get unit"); - String unit = getStringExpressionMessage(new ExpressionVariables(), task, task.getResult(), dataField.getExpression(), "Unit"); - numberMessagesParts.put(DashboardWidgetDataFieldTypeType.UNIT, unit); - break; - } - }); - if(!numberMessagesParts.containsKey(DashboardWidgetDataFieldTypeType.VALUE)) { - LOGGER.error("Value message is not generate from widget " + model.getObject().getIdentifier()); - return getPageBase().createStringResource(NUMBER_MESSAGE_UNKNOWN); - } - StringBuilder sb = new StringBuilder(); - sb.append(numberMessagesParts.get(DashboardWidgetDataFieldTypeType.VALUE)); - if(numberMessagesParts.containsKey(DashboardWidgetDataFieldTypeType.UNIT)) { - sb.append(" ").append(numberMessagesParts.get(DashboardWidgetDataFieldTypeType.UNIT)); - } - - try { - evaluateVariation(model.getObject(), variables); - } catch (Exception e) { - LOGGER.error(e.getMessage(), e); - } - - return getStringModel(sb.toString()); - } +// private IModel generateNumberMessage(DashboardWidgetPresentationType dashboardWidgetPresentationType, ExpressionVariables variables) { +// IModel model = (IModel)getDefaultModel(); +// Map numberMessagesParts = new HashMap(); +// model.getObject().getPresentation().getDataField().forEach(dataField -> { +// switch(dataField.getFieldType()) { +// +// case VALUE: +// Task task = getPageBase().createSimpleTask("Search domain collection"); +// try { +// String valueMessage = getStringExpressionMessage(variables, task, task.getResult(), +// dataField.getExpression(), "Get value message"); +// if(valueMessage == null) { +// valueMessage = getPageBase().createStringResource(NUMBER_MESSAGE_UNKNOWN).toString(); +// } +// numberMessagesParts.put(DashboardWidgetDataFieldTypeType.VALUE, valueMessage); +// } catch (Exception e) { +// LOGGER.error(e.getMessage(), e); +// } +// break; +// +// case UNIT: +// task = getPageBase().createSimpleTask("Get unit"); +// String unit = getStringExpressionMessage(new ExpressionVariables(), task, task.getResult(), dataField.getExpression(), "Unit"); +// numberMessagesParts.put(DashboardWidgetDataFieldTypeType.UNIT, unit); +// break; +// } +// }); +// if(!numberMessagesParts.containsKey(DashboardWidgetDataFieldTypeType.VALUE)) { +// LOGGER.error("Value message is not generate from widget " + model.getObject().getIdentifier()); +// return getPageBase().createStringResource(NUMBER_MESSAGE_UNKNOWN); +// } +// StringBuilder sb = new StringBuilder(); +// sb.append(numberMessagesParts.get(DashboardWidgetDataFieldTypeType.VALUE)); +// if(numberMessagesParts.containsKey(DashboardWidgetDataFieldTypeType.UNIT)) { +// sb.append(" ").append(numberMessagesParts.get(DashboardWidgetDataFieldTypeType.UNIT)); +// } +// +// try { +// evaluateVariation(model.getObject(), variables); +// } catch (Exception e) { +// LOGGER.error(e.getMessage(), e); +// } +// +// return getStringModel(sb.toString()); +// } - private void evaluateVariation(DashboardWidgetType widget, ExpressionVariables variables) { - - if(widget.getPresentation() != null) { - if(widget.getPresentation().getVariation() != null) { - widget.getPresentation().getVariation().forEach(variation -> { - Task task = getPageBase().createSimpleTask("Evaluate variation"); - PrismPropertyValue usingVariation; - try { - usingVariation = ExpressionUtil.evaluateCondition(variables, variation.getCondition(), null, getPageBase().getExpressionFactory(), - "Variation", task, task.getResult()); - - if(usingVariation != null && usingVariation.getRealValue() != null - && usingVariation.getRealValue().equals(Boolean.TRUE)) { - this.variationDisplay = variation.getDisplay(); - } - } catch (Exception e) { - LOGGER.error("Couldn't evaluate condition " + variation.toString(), e); - } - }); - } else { - LOGGER.error("Variation of presentation is not found in widget " + widget.getIdentifier()); - } - } else { - LOGGER.error("Presentation is not found in widget " + widget.getIdentifier()); - } - } +// private void evaluateVariation(DashboardWidgetType widget, ExpressionVariables variables) { +// +// if(widget.getPresentation() != null) { +// if(widget.getPresentation().getVariation() != null) { +// widget.getPresentation().getVariation().forEach(variation -> { +// Task task = getPageBase().createSimpleTask("Evaluate variation"); +// PrismPropertyValue usingVariation; +// try { +// usingVariation = ExpressionUtil.evaluateCondition(variables, variation.getCondition(), null, getPageBase().getExpressionFactory(), +// "Variation", task, task.getResult()); +// +// if(usingVariation != null && usingVariation.getRealValue() != null +// && usingVariation.getRealValue().equals(Boolean.TRUE)) { +// this.variationDisplay = variation.getDisplay(); +// } +// } catch (Exception e) { +// LOGGER.error("Couldn't evaluate condition " + variation.toString(), e); +// } +// }); +// } else { +// LOGGER.error("Variation of presentation is not found in widget " + widget.getIdentifier()); +// } +// } else { +// LOGGER.error("Presentation is not found in widget " + widget.getIdentifier()); +// } +// } - private int getObjectCount(ObjectCollectionType collection, boolean usingFilter) { - Class objectClass = (Class) getPageBase().getPrismContext().getSchemaRegistry() - .getCompileTimeClassForObjectType(collection.getType()); - SearchFilterType searchFilter = collection.getFilter(); - ObjectQuery query = getPageBase().getPrismContext().queryFactory().createQuery(); - if (searchFilter != null && usingFilter) { - try { - query.setFilter(getPageBase().getPrismContext().getQueryConverter().parseFilter(searchFilter, objectClass)); - } catch (Exception e) { - LOGGER.error("Filter couldn't parse in collection " + collection.toString(), e); - } - } - List> values = WebModelServiceUtils.searchObjects(objectClass, - query, new OperationResult("Load value Objects"), getPageBase()); - return values.size(); - } +// private int getObjectCount(ObjectCollectionType collection, boolean usingFilter) { +// Class objectClass = (Class) getPageBase().getPrismContext().getSchemaRegistry() +// .getCompileTimeClassForObjectType(collection.getType()); +// SearchFilterType searchFilter = collection.getFilter(); +// ObjectQuery query = getPageBase().getPrismContext().queryFactory().createQuery(); +// if (searchFilter != null && usingFilter) { +// try { +// query.setFilter(getPageBase().getPrismContext().getQueryConverter().parseFilter(searchFilter, objectClass)); +// } catch (Exception e) { +// LOGGER.error("Filter couldn't parse in collection " + collection.toString(), e); +// } +// } +// List> values = WebModelServiceUtils.searchObjects(objectClass, +// query, new OperationResult("Load value Objects"), getPageBase()); +// return values.size(); +// } protected void customInitLayout(WebMarkupContainer infoBox) { @@ -529,6 +560,7 @@ protected void customInitLayout(WebMarkupContainer infoBox) { private IModel getStringModel(String value){ return new IModel() { + private static final long serialVersionUID = 1L; @Override public String getObject() { @@ -557,6 +589,9 @@ protected WebPage getLinkRef(boolean onClick) { ObjectCollectionType collection = getObjectCollectionType(); if(collection != null && collection.getType() != null && collection.getType().getLocalPart() != null) { Class pageType = getLinksRefCollections().get(collection.getType().getLocalPart()); + if(pageType == null) { + return null; + } return getPageBase().createWebPage(pageType, null); } else { LOGGER.error("CollectionType from collectionRef is null in widget " + model.getObject().getIdentifier()); @@ -566,6 +601,9 @@ protected WebPage getLinkRef(boolean onClick) { collection = getObjectCollectionType(); if(collection != null && collection.getAuditSearch() != null && collection.getAuditSearch().getRecordQuery() != null) { Class pageType = getLinksRefCollections().get(AuditEventRecordItemType.COMPLEX_TYPE.getLocalPart()); + if(pageType == null) { + return null; + } AuditSearchDto searchDto = new AuditSearchDto(); searchDto.setCollection(collection); if(onClick){ @@ -583,6 +621,9 @@ protected WebPage getLinkRef(boolean onClick) { } QName typeName = WebComponentUtil.classToQName(getPageBase().getPrismContext(), object.getClass()); Class pageType = getLinksRefObjects().get(typeName); + if(pageType == null) { + return null; + } PageParameters parameters = new PageParameters(); if(onClick){ parameters.add(OnePageParameterEncoder.PARAMETER, object.getOid()); @@ -685,27 +726,27 @@ private ObjectType getObjectFromObjectRef() { return object; } - public static String getStringExpressionMessage(ExpressionVariables variables, - Task task, OperationResult result, ExpressionType expression, String shortDes) { - if (expression != null) { - Collection contentTypeList = null; - try { - contentTypeList = ExpressionUtil.evaluateStringExpression(variables, getPageBase().getPrismContext(), - expression, null, getPageBase().getExpressionFactory(), shortDes, task, result); - } catch (SchemaException | ExpressionEvaluationException | ObjectNotFoundException | CommunicationException - | ConfigurationException | SecurityViolationException e) { - LOGGER.error("Couldn't evaluate Expression " + expression.toString(), e); - } - if (contentTypeList == null || contentTypeList.isEmpty()) { - LOGGER.error("Expression " + expression + " returned nothing"); - return null; - } - if (contentTypeList.size() > 1) { - LOGGER.error("Expression returned more than 1 item. First item is used."); - } - return contentTypeList.iterator().next(); - } else { - return null; - } - } +// private static String getStringExpressionMessage(ExpressionVariables variables, +// Task task, OperationResult result, ExpressionType expression, String shortDes) { +// if (expression != null) { +// Collection contentTypeList = null; +// try { +// contentTypeList = ExpressionUtil.evaluateStringExpression(variables, getPageBase().getPrismContext(), +// expression, null, getPageBase().getExpressionFactory(), shortDes, task, result); +// } catch (SchemaException | ExpressionEvaluationException | ObjectNotFoundException | CommunicationException +// | ConfigurationException | SecurityViolationException e) { +// LOGGER.error("Couldn't evaluate Expression " + expression.toString(), e); +// } +// if (contentTypeList == null || contentTypeList.isEmpty()) { +// LOGGER.error("Expression " + expression + " returned nothing"); +// return null; +// } +// if (contentTypeList.size() > 1) { +// LOGGER.error("Expression returned more than 1 item. First item is used."); +// } +// return contentTypeList.iterator().next(); +// } else { +// return null; +// } +// } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/dto/AuditEventRecordProvider.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/dto/AuditEventRecordProvider.java index 81ce7311dbc..c33652968f0 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/dto/AuditEventRecordProvider.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/dto/AuditEventRecordProvider.java @@ -37,6 +37,7 @@ import com.evolveum.midpoint.audit.api.AuditEventRecord; import com.evolveum.midpoint.common.Clock; +import com.evolveum.midpoint.model.api.util.DashboardUtils; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.exception.CommunicationException; import com.evolveum.midpoint.util.exception.ConfigurationException; @@ -86,7 +87,7 @@ public class AuditEventRecordProvider extends BaseSortableDataProvider objectCollectionModel, @NotNull SerializableSupplier> parametersSupplier) { super(component); @@ -105,7 +106,7 @@ protected int internalSize() { String query; String origQuery; Map parameters = new HashMap(); - origQuery = createQuery(getCollectionForQuery(), parameters, false, getPage().getClock()); + origQuery = DashboardUtils.createQuery(getCollectionForQuery(), parameters, false, getPage().getClock()); if(StringUtils.isNotBlank(origQuery)) { query = generateFullQuery(origQuery, false, true); } else { @@ -114,7 +115,6 @@ protected int internalSize() { } try { Task task = getPage().createSimpleTask("internalSize"); - System.out.println("XXXXXXXXXx " + query); return (int) getAuditService().countObjects(query, parameters, task, task.getResult()); } catch (SecurityViolationException | SchemaException | ObjectNotFoundException | ExpressionEvaluationException | CommunicationException | ConfigurationException e) { // TODO: proper error handling (MID-3536) @@ -126,7 +126,7 @@ private List listRecords(boolean ordered, long first, long String query; String origQuery; Map parameters = new HashMap(); - origQuery = createQuery(getCollectionForQuery(), parameters, false, getPage().getClock()); + origQuery = DashboardUtils.createQuery(getCollectionForQuery(), parameters, false, getPage().getClock()); if(StringUtils.isNotBlank(origQuery)) { query = generateFullQuery(origQuery, ordered, false); } else { @@ -155,39 +155,39 @@ private List listRecords(boolean ordered, long first, long return auditRecordList; } - public static String createQuery(ObjectCollectionType collectionForQuery, Map parameters, - boolean forDomain, Clock clock) { - if(collectionForQuery == null) { - return null; - } - AuditSearchType auditSearch = collectionForQuery.getAuditSearch(); - if(auditSearch != null || StringUtils.isNotBlank(auditSearch.getRecordQuery())) { - Duration interval = auditSearch.getInterval(); - if(interval == null) { - return auditSearch.getRecordQuery(); - } - String origQuery = auditSearch.getRecordQuery(); - if(forDomain) { - origQuery = auditSearch.getDomainQuery(); - if(origQuery == null) { - return null; - } - } - String [] partsOfQuery = origQuery.split("where"); - if(interval.getSign() == 1) { - interval = interval.negate(); - } - Date date = new Date(clock.currentTimeMillis()); - interval.addTo(date); - String query = partsOfQuery[0] + "where " + TIMESTAMP_VALUE_NAME + " >= " + ":from" + " "; - parameters.put(PARAMETER_FROM, date); - if(partsOfQuery.length > 1) { - query+= "and" +partsOfQuery[1]; - } - return query; - } - return null; - } +// public static String createQuery(ObjectCollectionType collectionForQuery, Map parameters, +// boolean forDomain, Clock clock) { +// if(collectionForQuery == null) { +// return null; +// } +// AuditSearchType auditSearch = collectionForQuery.getAuditSearch(); +// if(auditSearch != null || StringUtils.isNotBlank(auditSearch.getRecordQuery())) { +// Duration interval = auditSearch.getInterval(); +// if(interval == null) { +// return auditSearch.getRecordQuery(); +// } +// String origQuery = auditSearch.getRecordQuery(); +// if(forDomain) { +// origQuery = auditSearch.getDomainQuery(); +// if(origQuery == null) { +// return null; +// } +// } +// String [] partsOfQuery = origQuery.split("where"); +// if(interval.getSign() == 1) { +// interval = interval.negate(); +// } +// Date date = new Date(clock.currentTimeMillis()); +// interval.addTo(date); +// String query = partsOfQuery[0] + "where " + TIMESTAMP_VALUE_NAME + " >= " + ":from" + " "; +// parameters.put(PARAMETER_FROM, date); +// if(partsOfQuery.length > 1) { +// query+= "and" +partsOfQuery[1]; +// } +// return query; +// } +// return null; +// } @SuppressWarnings("unused") diff --git a/model/model-api/pom.xml b/model/model-api/pom.xml index aea95b3ce70..84b765aeada 100644 --- a/model/model-api/pom.xml +++ b/model/model-api/pom.xml @@ -77,6 +77,11 @@ task-api 4.0-SNAPSHOT + + com.evolveum.midpoint.repo + repo-common + 4.0-SNAPSHOT + com.evolveum.midpoint.repo security-api diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/DashboardWidget.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/DashboardWidget.java new file mode 100644 index 00000000000..2c612bcc4f1 --- /dev/null +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/DashboardWidget.java @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2010-2019 Evolveum + * + * 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.evolveum.midpoint.model.api; + +import com.evolveum.midpoint.xml.ns._public.common.common_3.DashboardWidgetType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.DisplayType; + +/** + * @author skublik + */ +public class DashboardWidget { + + private DisplayType display; + private String numberMessage; + private DashboardWidgetType widget; + + public DashboardWidget() { + } + + public DashboardWidget(DashboardWidgetType widget, DisplayType display, String numberMessage) { + this.widget = widget; + this.display = display; + this.numberMessage = numberMessage; + } + + public DisplayType getDisplay() { + return display; + } + + public void setDisplay(DisplayType display) { + this.display = display; + } + + public String getNumberMessage() { + return numberMessage; + } + + public void setNumberMessage(String numberMessage) { + this.numberMessage = numberMessage; + } + + public DashboardWidgetType getWidget() { + return widget; + } + + public void setWidget(DashboardWidgetType widget) { + this.widget = widget; + } + + public String getLabel() { + if(getDisplay() != null && getDisplay().getLabel() != null) { + return getDisplay().getLabel().toString(); + } else { + return getWidget().getIdentifier(); + } + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("{widgetIdentifier:").append(widget == null ? null : widget.getIdentifier()) + .append(", numberMessage:").append(numberMessage) + .append(", display:").append(display).append("}"); + return sb.toString(); + } +} diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/util/DashboardUtils.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/util/DashboardUtils.java new file mode 100644 index 00000000000..b1242b4a55e --- /dev/null +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/util/DashboardUtils.java @@ -0,0 +1,647 @@ +/** + * Copyright (c) 2010-2019 Evolveum + * + * 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.evolveum.midpoint.model.api.util; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.xml.datatype.Duration; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.springframework.beans.factory.annotation.Autowired; + +import com.evolveum.midpoint.audit.api.AuditService; +import com.evolveum.midpoint.common.Clock; +import com.evolveum.midpoint.model.api.ModelInteractionService; +import com.evolveum.midpoint.model.api.ModelService; +import com.evolveum.midpoint.model.api.DashboardWidget; +import com.evolveum.midpoint.model.api.authentication.CompiledObjectCollectionView; +import com.evolveum.midpoint.model.api.context.EvaluatedPolicyRule; +import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.PrismPropertyValue; +import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.repo.common.expression.ExpressionFactory; +import com.evolveum.midpoint.repo.common.expression.ExpressionUtil; +import com.evolveum.midpoint.repo.common.expression.ExpressionVariables; +import com.evolveum.midpoint.schema.constants.ExpressionConstants; +import com.evolveum.midpoint.schema.expression.VariablesMap; +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.task.api.Task; +import com.evolveum.midpoint.task.api.TaskManager; +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.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AuditSearchType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.DashboardWidgetDataFieldTypeType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.DashboardWidgetPresentationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.DashboardWidgetSourceTypeType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.DashboardWidgetType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.DashboardWidgetVariationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.DisplayType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ExpressionType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.IconType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.IntegerStatType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectCollectionType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; +import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType; + +/** + * @author skublik + */ +public class DashboardUtils { + + private static final Trace LOGGER = TraceManager.getTrace(DashboardUtils.class); + + public static final String VAR_PROPORTIONAL = "proportional"; + private static final String VAR_POLICY_SITUATIONS = "policySituations"; + + public static final String PARAMETER_FROM = "from"; + private static final String AUDIT_RECORDS_ORDER_BY = " order by aer.timestamp desc"; + private static final String TIMESTAMP_VALUE_NAME = "aer.timestamp"; + +// @Autowired private static TaskManager taskManager; +// @Autowired private static AuditService auditService; +// @Autowired private static PrismContext prismContext; +// @Autowired private static Clock clock; +// @Autowired private static ModelInteractionService modelInteractionService; +// @Autowired private static ModelService modelService; +// @Autowired private static ExpressionFactory expressionFactory; + + public static DashboardWidget createWidgetData(DashboardWidgetType widget, ModelService modelService, + TaskManager taskManager, ExpressionFactory expressionFactory, AuditService auditService, + Clock clock, ModelInteractionService modelInteractionService) { + + Validate.notNull(widget, "Widget is null"); + Validate.notNull(modelService, "ModelService is null"); + Validate.notNull(taskManager, "TaskManager is null"); + Validate.notNull(expressionFactory, "ExpressionFactory is null"); + Validate.notNull(auditService, "AuditService is null"); + Validate.notNull(clock, "Clock is null"); + Validate.notNull(modelInteractionService, "ModelInteractionService is null"); + + DashboardWidget data = new DashboardWidget(); + getNumberMessage(widget, modelService, + modelService.getPrismContext(), taskManager, expressionFactory, + auditService, clock, modelInteractionService, data); + data.setWidget(widget); + if(data.getDisplay() == null) { + data.setDisplay(widget.getDisplay()); + } + LOGGER.debug("Widget Data: {}", data); + return data; + } + + private static DisplayType combinateDisplay(DisplayType display, DisplayType variationDisplay) { + DisplayType combinatedDisplay = new DisplayType(); + if (variationDisplay == null) { + return display; + } + if(display == null) { + return variationDisplay; + } + if(StringUtils.isBlank(variationDisplay.getColor())) { + combinatedDisplay.setColor(display.getColor()); + } else { + combinatedDisplay.setColor(variationDisplay.getColor()); + } + if(StringUtils.isBlank(variationDisplay.getCssClass())) { + combinatedDisplay.setCssClass(display.getCssClass()); + } else { + combinatedDisplay.setCssClass(variationDisplay.getCssClass()); + } + if(StringUtils.isBlank(variationDisplay.getCssStyle())) { + combinatedDisplay.setCssStyle(display.getCssStyle()); + } else { + combinatedDisplay.setCssStyle(variationDisplay.getCssStyle()); + } + if(variationDisplay.getHelp() == null) { + combinatedDisplay.setHelp(display.getHelp()); + } else { + combinatedDisplay.setHelp(variationDisplay.getHelp()); + } + if(variationDisplay.getLabel() == null) { + combinatedDisplay.setLabel(display.getLabel()); + } else { + combinatedDisplay.setLabel(variationDisplay.getLabel()); + } + if(variationDisplay.getPluralLabel() == null) { + combinatedDisplay.setPluralLabel(display.getPluralLabel()); + } else { + combinatedDisplay.setPluralLabel(variationDisplay.getPluralLabel()); + } + if(variationDisplay.getTooltip() == null) { + combinatedDisplay.setTooltip(display.getTooltip()); + } else { + combinatedDisplay.setTooltip(variationDisplay.getTooltip()); + } + if(variationDisplay.getIcon() == null) { + combinatedDisplay.setIcon(display.getIcon()); + } else if(display.getIcon() != null){ + IconType icon = new IconType(); + if(StringUtils.isBlank(variationDisplay.getIcon().getCssClass())) { + icon.setCssClass(display.getIcon().getCssClass()); + } else { + icon.setCssClass(variationDisplay.getIcon().getCssClass()); + } + if(StringUtils.isBlank(variationDisplay.getIcon().getColor())) { + icon.setColor(display.getIcon().getColor()); + } else { + icon.setColor(variationDisplay.getIcon().getColor()); + } + if(StringUtils.isBlank(variationDisplay.getIcon().getImageUrl())) { + icon.setImageUrl(display.getIcon().getImageUrl()); + } else { + icon.setImageUrl(variationDisplay.getIcon().getImageUrl()); + } + combinatedDisplay.setIcon(icon); + } + + return combinatedDisplay; + } + + public static DashboardWidgetSourceTypeType getSourceType(DashboardWidgetType widget) { + if(isSourceTypeOfDataNull(widget)) { + return null; + } + return widget.getData().getSourceType(); + } + + private static String getNumberMessage(DashboardWidgetType widget, ModelService modelService, + PrismContext prismContext, TaskManager taskManager, ExpressionFactory expressionFactory, + AuditService auditService, Clock clock, ModelInteractionService modelInteractionService, DashboardWidget data) { + DashboardWidgetSourceTypeType sourceType = getSourceType(widget); + DashboardWidgetPresentationType presentation = widget.getPresentation(); + switch (sourceType) { + case OBJECT_COLLECTION: + if(!isDataFieldsOfPresentationNullOrEmpty(presentation)) { + return generateNumberMessageForCollection(widget, modelInteractionService, taskManager, + expressionFactory, prismContext, modelService, data); + } + break; + case AUDIT_SEARCH: + if(!isDataFieldsOfPresentationNullOrEmpty(presentation)) { + return generateNumberMessageForAuditSearch(widget, auditService, taskManager, + expressionFactory, prismContext, clock, modelService, data); + } + break; + case OBJECT: + if(!isDataFieldsOfPresentationNullOrEmpty(presentation)) { + return generateNumberMessageForObject(widget, modelService, prismContext, + taskManager, expressionFactory, data); + } + break; + } + return null; + } + + public static boolean isDataFieldsOfPresentationNullOrEmpty(DashboardWidgetPresentationType presentation) { + if(presentation != null) { + if(presentation.getDataField() != null) { + if(!presentation.getDataField().isEmpty()) { + return false; + } else { + LOGGER.error("DataField of presentation is empty"); + } + } else { + LOGGER.error("DataField of presentation is not defined"); + } + } else { + LOGGER.error("Presentation of widget is not defined"); + } + + return true; + } + + private static String generateNumberMessageForObject(DashboardWidgetType widget, ModelService modelService, + PrismContext prismContext, TaskManager taskManager, ExpressionFactory expressionFactory, DashboardWidget data) { + ObjectType object = getObjectFromObjectRef(widget, modelService, prismContext, taskManager); + if(object == null) { + return null; + } + return generateNumberMessage(widget, createVariables(object.asPrismObject(), null, null), taskManager, + expressionFactory, prismContext, data); + } + + private static String generateNumberMessageForAuditSearch(DashboardWidgetType widget, AuditService auditService, + TaskManager taskManager, ExpressionFactory expressionFactory, PrismContext prismContext, Clock clock, + ModelService modelService, DashboardWidget data) { + ObjectCollectionType collection = getObjectCollectionType(widget, taskManager, prismContext, modelService); + if(collection == null) { + return null; + } + AuditSearchType auditSearch = collection.getAuditSearch(); + if(auditSearch == null) { + LOGGER.error("AuditSearch of ObjectCollection is not found in widget " + + widget.getIdentifier()); + return null; + } + if(auditSearch.getRecordQuery() == null) { + LOGGER.error("RecordQuery of auditSearch is not defined in widget " + + widget.getIdentifier()); + return null; + } + + Map parameters = new HashMap(); + String query = getQueryForCount(createQuery(collection, + parameters, false, clock)); + LOGGER.debug("Parameters for select: " + parameters); + int value = (int) auditService.countObjects( + query, parameters); + Integer domainValue = null; + if(auditSearch.getDomainQuery() == null) { + LOGGER.error("DomainQuery of auditSearch is not defined"); + } else { + parameters = new HashMap(); + query = getQueryForCount(createQuery(collection, + parameters, true, clock)); + LOGGER.debug("Parameters for select: " + parameters); + domainValue = (int) auditService.countObjects( + query, parameters); + } + LOGGER.debug("Value: {}, Domain value: {}", value, domainValue); + IntegerStatType statType = generateIntegerStat(value, domainValue); + return generateNumberMessage(widget, createVariables(null, statType, null), taskManager, expressionFactory, + prismContext, data); + } + + private static String getQueryForCount(String query) { + query = "select count (*) " + query; + query = query.split("order")[0]; + LOGGER.debug("Query for select: " + query); + return query; + } + + public static String getQueryForListRecords(String query) { + query = query + AUDIT_RECORDS_ORDER_BY; + LOGGER.debug("Query for select: " + query); + return query; + } + + private static String generateNumberMessageForCollection(DashboardWidgetType widget, + ModelInteractionService modelInteractionService, TaskManager taskManager, + ExpressionFactory expressionFactory, PrismContext prismContext, ModelService modelService, DashboardWidget data) { + ObjectCollectionType valueCollection = getObjectCollectionType(widget, taskManager, prismContext, + modelService); + if(valueCollection != null && valueCollection.getType() != null && + valueCollection.getType().getLocalPart() != null) { + int value = getObjectCount(valueCollection, true, prismContext, taskManager, modelService); + + int domainValue; + if( valueCollection.getDomain() != null && valueCollection.getDomain().getCollectionRef() != null) { +// ObjectCollectionType domainCollection = (ObjectCollectionType) getObjectCollectionType(widget, +// taskManager, prismContext, modelService); + ObjectReferenceType ref = valueCollection.getDomain().getCollectionRef(); + ObjectCollectionType domainCollection = (ObjectCollectionType)getObjectTypeFromObjectRef(ref, taskManager, prismContext, modelService); + if(domainCollection == null) { + return null; + } +// ObjectCollectionType domainCollection = (ObjectCollectionType)WebModelServiceUtils.loadObject(ref, +// getPageBase(), task, task.getResult()).getRealValue(); + domainValue = getObjectCount(domainCollection, true, prismContext, taskManager, modelService); + } else { + LOGGER.error("Domain or collectionRef in domain is null in collection " + valueCollection.toString()); + LOGGER.trace("Using filter for all object based on type"); + domainValue = getObjectCount(valueCollection, false, prismContext, taskManager, modelService); + } + IntegerStatType statType = generateIntegerStat(value, domainValue); + + Task task = taskManager.createTaskInstance("Evaluate collection"); + try { + CompiledObjectCollectionView compiledCollection = modelInteractionService.compileObjectCollectionView( + valueCollection.asPrismObject(), null, task, task.getResult()); + Collection evalPolicyRules = modelInteractionService.evaluateCollectionPolicyRules( + valueCollection.asPrismObject(), compiledCollection, null, task, task.getResult()); + Collection policySituations = new ArrayList(); + for(EvaluatedPolicyRule evalPolicyRule : evalPolicyRules) { + if(!evalPolicyRule.getAllTriggers().isEmpty()) { + policySituations.add(evalPolicyRule.getPolicySituation()); + } + } + return generateNumberMessage(widget, createVariables(null, statType, policySituations), + taskManager, expressionFactory, prismContext, data); + } catch (Exception e) { + LOGGER.error(e.getMessage(), e); + return null; + } + + } else { + LOGGER.error("CollectionType from collectionRef is null in widget " + widget.getIdentifier()); + } + return null; + } + + private static ExpressionVariables createVariables(PrismObject object, + IntegerStatType statType, Collection policySituations) { + ExpressionVariables variables = new ExpressionVariables(); + if(statType != null || policySituations != null) { + VariablesMap variablesMap = new VariablesMap(); + if(statType != null ) { + variablesMap.put(ExpressionConstants.VAR_INPUT, statType, statType.getClass()); + variablesMap.put(VAR_PROPORTIONAL, statType, statType.getClass()); + } + if(policySituations != null) { + variablesMap.put(VAR_POLICY_SITUATIONS, policySituations, EvaluatedPolicyRule.class); + } + variables.addVariableDefinitions(variablesMap ); + } + if(object != null) { + variables.addVariableDefinition(ExpressionConstants.VAR_OBJECT, object, object.getDefinition()); + } + + return variables; + } + + private static IntegerStatType generateIntegerStat(Integer value, Integer domainValue){ + IntegerStatType statType = new IntegerStatType(); + statType.setValue(value); + statType.setDomain(domainValue); + return statType; + } + + private static String generateNumberMessage(DashboardWidgetType widget, ExpressionVariables variables, + TaskManager taskManager, ExpressionFactory expressionFactory, PrismContext prismContext, DashboardWidget data) { + Map numberMessagesParts = new HashMap(); + widget.getPresentation().getDataField().forEach(dataField -> { + switch(dataField.getFieldType()) { + + case VALUE: + Task task = taskManager.createTaskInstance("Search domain collection"); + try { + String valueMessage = getStringExpressionMessage(variables, task, task.getResult(), + dataField.getExpression(), "Get value message", prismContext, expressionFactory); + if(valueMessage != null) { + numberMessagesParts.put(DashboardWidgetDataFieldTypeType.VALUE, valueMessage); + } + } catch (Exception e) { + LOGGER.error(e.getMessage(), e); + } + break; + + case UNIT: + task = taskManager.createTaskInstance("Get unit"); + String unit = getStringExpressionMessage(new ExpressionVariables(), task, + task.getResult(), dataField.getExpression(), "Unit", + prismContext, expressionFactory); + numberMessagesParts.put(DashboardWidgetDataFieldTypeType.UNIT, unit); + break; + } + }); + if(!numberMessagesParts.containsKey(DashboardWidgetDataFieldTypeType.VALUE)) { + LOGGER.error("Value message is not generate from widget " + widget.getIdentifier()); + return null; + } + StringBuilder sb = new StringBuilder(); + sb.append(numberMessagesParts.get(DashboardWidgetDataFieldTypeType.VALUE)); + if(numberMessagesParts.containsKey(DashboardWidgetDataFieldTypeType.UNIT)) { + sb.append(" ").append(numberMessagesParts.get(DashboardWidgetDataFieldTypeType.UNIT)); + } + + try { + evaluateVariation(widget, variables, taskManager, expressionFactory, data); + } catch (Exception e) { + LOGGER.error(e.getMessage(), e); + } + data.setNumberMessage(sb.toString()); + return sb.toString(); + } + + private static void evaluateVariation(DashboardWidgetType widget, ExpressionVariables variables, TaskManager taskManager, + ExpressionFactory expressionFactory, DashboardWidget data) { + + if(widget.getPresentation() != null) { + if(widget.getPresentation().getVariation() != null) { + for(DashboardWidgetVariationType variation : widget.getPresentation().getVariation()) { + Task task = taskManager.createTaskInstance("Evaluate variation"); + PrismPropertyValue usingVariation; + try { + usingVariation = ExpressionUtil.evaluateCondition(variables, variation.getCondition(), null, + expressionFactory, + "Variation", task, task.getResult()); + + if(usingVariation != null && usingVariation.getRealValue() != null + && usingVariation.getRealValue().equals(Boolean.TRUE)) { + data.setDisplay(combinateDisplay(widget.getDisplay(), variation.getDisplay())); + } else { + data.setDisplay(widget.getDisplay()); + } + } catch (Exception e) { + LOGGER.error("Couldn't evaluate condition " + variation.toString(), e); + } + } + } else { + LOGGER.error("Variation of presentation is not found in widget " + widget.getIdentifier()); + } + } else { + LOGGER.error("Presentation is not found in widget " + widget.getIdentifier()); + } + } + + private static int getObjectCount(ObjectCollectionType collection, boolean usingFilter, PrismContext prismContext, + TaskManager taskManager, ModelService modelService) { + List> values = searchObjectFromCollection(collection, usingFilter, + prismContext, taskManager, modelService); + if(values != null) { + LOGGER.debug("Return count: {}", values.size()); + return values.size(); + } + return 0; + } + + public static List> searchObjectFromCollection(ObjectCollectionType collection, boolean usingFilter, PrismContext prismContext, + TaskManager taskManager, ModelService modelService){ + Class type = (Class) prismContext.getSchemaRegistry() + .getCompileTimeClassForObjectType(collection.getType()); + SearchFilterType searchFilter = collection.getFilter(); + ObjectQuery query = prismContext.queryFactory().createQuery(); + if (searchFilter != null && usingFilter) { + try { + query.setFilter(prismContext.getQueryConverter().parseFilter(searchFilter, type)); + } catch (Exception e) { + LOGGER.error("Filter couldn't parse in collection " + collection.toString(), e); + } + } + Task task =taskManager.createTaskInstance("Load value Objects"); + List> values; + try { + values = modelService.searchObjects(type, query, null, task, task.getResult()); + return values; + } catch (Exception e) { + LOGGER.error("Couldn't search objects", e); + } + return null; + } + + private static boolean isDataNull(DashboardWidgetType widget) { + if(widget.getData() == null) { + LOGGER.error("Data is not found in widget " + widget.getIdentifier()); + return true; + } + return false; + } + + private static boolean isSourceTypeOfDataNull(DashboardWidgetType widget) { + if(isDataNull(widget)) { + return true; + } + if(widget.getData().getSourceType() == null) { + LOGGER.error("SourceType of data is not found in widget " + widget.getIdentifier()); + return true; + } + return false; + } + + private static boolean isCollectionOfDataNull(DashboardWidgetType widget) { + if(isDataNull(widget)) { + return true; + } + if(widget.getData().getCollection() == null) { + LOGGER.error("Collection of data is not found in widget " + widget.getIdentifier()); + return true; + } + return false; + } + + private static boolean isCollectionRefOfCollectionNull(DashboardWidgetType widget) { + if(isDataNull(widget)) { + return true; + } + if(isCollectionOfDataNull(widget)) { + return true; + } + ObjectReferenceType ref = widget.getData().getCollection().getCollectionRef(); + if(ref == null) { + LOGGER.error("CollectionRef of collection is not found in widget " + widget.getIdentifier()); + return true; + } + return false; + } + + public static ObjectCollectionType getObjectCollectionType(DashboardWidgetType widget, TaskManager taskManager, + PrismContext prismContext, ModelService modelService) { + if(isCollectionRefOfCollectionNull(widget)) { + return null; + } + ObjectReferenceType ref = widget.getData().getCollection().getCollectionRef(); + ObjectCollectionType collection = (ObjectCollectionType) getObjectTypeFromObjectRef(ref, taskManager, prismContext, + modelService); + return collection; + } + + private static ObjectType getObjectFromObjectRef(DashboardWidgetType widget, ModelService modelService, + PrismContext prismContext, TaskManager taskManager) { + if(isDataNull(widget)) { + return null; + } + ObjectReferenceType ref = widget.getData().getObjectRef(); + if(ref == null) { + LOGGER.error("ObjectRef of data is not found in widget " + widget.getIdentifier()); + return null; + } + ObjectType object = getObjectTypeFromObjectRef(ref, taskManager, prismContext, modelService); + if(object == null) { + LOGGER.error("Object from ObjectRef " + ref + " is null in widget " + widget.getIdentifier()); + } + return object; + } + + public static ObjectType getObjectTypeFromObjectRef(ObjectReferenceType ref, TaskManager taskManager, + PrismContext prismContext, ModelService modelService) { + Task task = taskManager.createTaskInstance("Get object"); + Class type = prismContext.getSchemaRegistry().determineClassForType(ref.getType()); + PrismObject object; + + try { + object = modelService.getObject(type, + ref.getOid(), null, task, task.getResult()); + return object.asObjectable(); + } catch (Exception e) { + LOGGER.error("Couldn't get object from objectRef " + ref, e); + } + return null; + } + + private static String getStringExpressionMessage(ExpressionVariables variables, + Task task, OperationResult result, ExpressionType expression, String shortDes, PrismContext prismContext, + ExpressionFactory expressionFactory) { + if (expression != null) { + Collection contentTypeList = null; + try { + contentTypeList = ExpressionUtil.evaluateStringExpression(variables, prismContext, + expression, null, expressionFactory, shortDes, task, result); + } catch (SchemaException | ExpressionEvaluationException | ObjectNotFoundException | CommunicationException + | ConfigurationException | SecurityViolationException e) { + LOGGER.error("Couldn't evaluate Expression " + expression.toString(), e); + } + if (contentTypeList == null || contentTypeList.isEmpty()) { + LOGGER.error("Expression " + expression + " returned nothing"); + return null; + } + if (contentTypeList.size() > 1) { + LOGGER.error("Expression returned more than 1 item. First item is used."); + } + return contentTypeList.iterator().next(); + } else { + return null; + } + } + + public static String createQuery(ObjectCollectionType collectionForQuery, Map parameters, + boolean forDomain, Clock clock) { + if(collectionForQuery == null) { + return null; + } + AuditSearchType auditSearch = collectionForQuery.getAuditSearch(); + if(auditSearch != null || StringUtils.isNotBlank(auditSearch.getRecordQuery())) { + Duration interval = auditSearch.getInterval(); + if(interval == null) { + return auditSearch.getRecordQuery(); + } + String origQuery = auditSearch.getRecordQuery(); + if(forDomain) { + origQuery = auditSearch.getDomainQuery(); + if(origQuery == null) { + return null; + } + } + String [] partsOfQuery = origQuery.split("where"); + if(interval.getSign() == 1) { + interval = interval.negate(); + } + Date date = new Date(clock.currentTimeMillis()); + interval.addTo(date); + String query = partsOfQuery[0] + "where " + TIMESTAMP_VALUE_NAME + " >= " + ":from" + " "; + parameters.put(PARAMETER_FROM, date); + if(partsOfQuery.length > 1) { + query+= "and" +partsOfQuery[1]; + } + return query; + } + return null; + } + +} diff --git a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/GeneralNotifier.java b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/GeneralNotifier.java index e631d55dcbc..6500a4bacc9 100644 --- a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/GeneralNotifier.java +++ b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/GeneralNotifier.java @@ -150,6 +150,8 @@ public boolean processEvent(Event event, EventHandlerType eventHandlerType, Noti message.setContentType(contentType); } else if (generalNotifierType.getContentType() != null) { message.setContentType(generalNotifierType.getContentType()); + } else if (getContentType() != null) { + message.setContentType(getContentType()); } message.setSubject(subject); @@ -184,6 +186,10 @@ public boolean processEvent(Event event, EventHandlerType eventHandlerType, Noti return true; // not-applicable notifiers do not stop processing of other notifiers } + protected String getContentType() { + return null; + } + protected boolean quickCheckApplicability(Event event, GeneralNotifierType generalNotifierType, OperationResult result) { return true; } diff --git a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/SimpleReportNotifier.java b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/SimpleReportNotifier.java index d20fdc50142..b25c40ac274 100644 --- a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/SimpleReportNotifier.java +++ b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/SimpleReportNotifier.java @@ -135,8 +135,7 @@ protected String getBody(Event event, GeneralNotifierType generalNotifierType, S byte[] encoded = Files.readAllBytes(Paths.get(reportOutput.asObjectable().getFilePath())); body = new String(encoded, Charset.defaultCharset()); } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + getLogger().error("Couldn't create body from ReportOutput with oid " + outputOid, e); } return body; } @@ -145,5 +144,9 @@ protected String getBody(Event event, GeneralNotifierType generalNotifierType, S protected Trace getLogger() { return LOGGER; } + + protected String getContentType() { + return "text/html"; + }; } diff --git a/model/report-impl/pom.xml b/model/report-impl/pom.xml index 7cbacdb404c..ea7eb346e28 100644 --- a/model/report-impl/pom.xml +++ b/model/report-impl/pom.xml @@ -47,16 +47,6 @@ https://fisheye.evolveum.com/browse/midPoint - - org.apache.commons - commons-collections4 - 4.1 - - - org.apache.commons - commons-text - 1.6 - com.evolveum.midpoint.model report-api @@ -209,6 +199,14 @@ javax.ws.rs javax.ws.rs-api + + + + + com.j2html + j2html + 1.4.0 + org.apache.cxf diff --git a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportHTMLCreateTaskHandler.java b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportHTMLCreateTaskHandler.java index 9075f619297..39df61b0278 100644 --- a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportHTMLCreateTaskHandler.java +++ b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportHTMLCreateTaskHandler.java @@ -18,59 +18,90 @@ import java.io.File; import java.io.InputStream; import java.nio.charset.Charset; +import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Arrays; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Locale; import java.util.Map; -import java.util.stream.Collectors; +import java.util.Set; -import javax.annotation.PostConstruct; +import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; import com.evolveum.midpoint.repo.common.ObjectResolver; +import com.evolveum.midpoint.repo.common.expression.ExpressionFactory; -import org.apache.commons.collections4.map.HashedMap; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; -import org.apache.commons.text.StringEscapeUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; import com.evolveum.midpoint.audit.api.AuditEventRecord; import com.evolveum.midpoint.audit.api.AuditService; +import com.evolveum.midpoint.common.Clock; +import com.evolveum.midpoint.model.api.ModelInteractionService; import com.evolveum.midpoint.model.api.ModelService; +import com.evolveum.midpoint.model.api.DashboardWidget; +import com.evolveum.midpoint.model.api.util.DashboardUtils; +import com.evolveum.midpoint.prism.Item; +import com.evolveum.midpoint.prism.PrismContainer; import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.query.ObjectQuery; -import com.evolveum.midpoint.prism.xml.XmlTypeConverter; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.PrismProperty; +import com.evolveum.midpoint.prism.PrismPropertyValue; +import com.evolveum.midpoint.prism.PrismReference; +import com.evolveum.midpoint.prism.PrismValue; +import com.evolveum.midpoint.prism.Referencable; +import com.evolveum.midpoint.prism.path.ItemName; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.task.api.RunningTask; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.task.api.TaskManager; import com.evolveum.midpoint.task.api.TaskRunResult; import com.evolveum.midpoint.task.api.TaskRunResult.TaskRunResultStatus; -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.QNameUtil; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordItemType; import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordType; -import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventStageType; -import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventTypeType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AvailabilityStatusType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractRoleType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorConfigurationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.DashboardType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.DashboardWidgetPresentationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.DashboardWidgetSourceTypeType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.DashboardWidgetType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.DisplayType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ExportType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultStatusType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationalStateType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectCollectionType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ReportEngineSelectionType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ReportType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ServiceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskExecutionStatusType; import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskPartitionDefinitionType; import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; +import com.fasterxml.jackson.databind.deser.ValueInstantiator.Gettable; + +import j2html.TagCreator; +import j2html.tags.ContainerTag; /** * @author skublik @@ -79,331 +110,520 @@ @Component public class ReportHTMLCreateTaskHandler extends ReportJasperCreateTaskHandler { - public static final String REPORT_HTML_CREATE_TASK_URI = "http://midpoint.evolveum.com/xml/ns/public/report/html/create/handler-3"; - private static final Trace LOGGER = TraceManager.getTrace(ReportHTMLCreateTaskHandler.class); - - private static String START_THEAD = ""; - private static String START_TBODY = ""; - private static final String REPORT_ADMIN_DASHBOARD_SUBTYPE = "admin-dashboard-report"; - private static final String REPORT_HTML_TEMPLATE_FILE_NAME = "admin-dashboard-report-template.html"; - - - @Autowired private TaskManager taskManager; - @Autowired private AuditService auditService; - @Autowired private ModelService modelService; - @Autowired private PrismContext prismContext; - @Autowired @Qualifier("modelObjectResolver") private ObjectResolver objectResolver; - - @PostConstruct - private void initialize() { - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Registering with taskManager as a handler for " + REPORT_HTML_CREATE_TASK_URI); - } - taskManager.registerHandler(REPORT_HTML_CREATE_TASK_URI, this); - } - - @Override - public TaskRunResult run(RunningTask task, TaskPartitionDefinitionType partition) { - // TODO Auto-generated method stub - OperationResult parentResult = task.getResult(); - OperationResult result = parentResult.createSubresult(ReportHTMLCreateTaskHandler.class.getSimpleName() + ".run"); - - TaskRunResult runResult = new TaskRunResult(); - runResult.setOperationResult(result); - - super.recordProgress(task, 0, result); - try { - ReportType parentReport = objectResolver.resolve(task.getObjectRef(), ReportType.class, null, "resolving report", task, result); - - if(!parentReport.getSubtype().contains(REPORT_ADMIN_DASHBOARD_SUBTYPE)) { - parentReport.setExport(ExportType.HTML); - return super.run(task); - } - - String template = ""; - ClassLoader classLoader = getClass().getClassLoader(); - InputStream in = classLoader.getResourceAsStream(REPORT_HTML_TEMPLATE_FILE_NAME); - byte[] data = IOUtils.toByteArray(in); - template = new String(data, Charset.defaultCharset()); - - - String[] parts = template.split(START_THEAD); - StringBuilder body = new StringBuilder(parts[0]); - Task opTask = taskManager.createTaskInstance(); - body.append(createTHead()); - parts = parts[1].split(START_TBODY); - body.append(parts[0]); - body.append(createTBody(opTask)); - body.append(parts[1]); - - String reportFilePath = getDestinationFileName(parentReport); - FileUtils.writeByteArrayToFile(new File(reportFilePath), body.toString().getBytes()); - super.saveReportOutputType(reportFilePath, parentReport, task, result); - LOGGER.trace("create report output type : {}", reportFilePath); - - if (parentReport.getPostReportScript() != null) { - super.processPostReportScript(parentReport, reportFilePath, task, result); - } - result.computeStatus(); - - } catch (Exception ex) { - LOGGER.error("CreateReport: {}", ex.getMessage(), ex); - result.recordFatalError(ex.getMessage(), ex); - runResult.setRunResultStatus(TaskRunResultStatus.PERMANENT_ERROR); - return runResult; - } - - // This "run" is finished. But the task goes on ... - runResult.setRunResultStatus(TaskRunResultStatus.FINISHED); - LOGGER.trace("CreateReportTaskHandler.run stopping"); - return runResult; - } - - private String createTHead() { - List childElements = new ArrayList(); - for(String value : getHead()) { - HTMLElement div = new HTMLElement("div").addChildElement(new HTMLElement("span").setClasses("sortableLabel").setText(value)); - childElements.add(new HTMLElement("th").addChildElement(div)); + public static final String REPORT_HTML_CREATE_TASK_URI = "http://midpoint.evolveum.com/xml/ns/public/report/html/create/handler-3"; + private static final Trace LOGGER = TraceManager.getTrace(ReportHTMLCreateTaskHandler.class); + + private static final String REPORT_CSS_STYLE_FILE_NAME = "dashboard-report-style.css"; + private static final String LABEL_COLUMN = "Label"; + private static final String NUMBER_COLUMN = "Number"; + private static final String STATUS_COLUMN = "Status"; + private static final String TIME_COLUMN = "Time"; + private static final String INITIATOR_COLUMN = "Initiator"; + private static final String EVENT_STAGE_COLUMN = "Event stage"; + private static final String EVENT_TYPE_COLUMN = "Event type"; + private static final String TARGET_COLUMN = "Target"; + private static final String TARGET_OWNER_COLUMN = "Target owner"; + private static final String CHANNEL_COLUMN = "Channel"; + private static final String OUTCOME_COLUMN = "Outcome"; + private static final String NAME_COLUMN = "Name"; + private static final String CONNECTOR_TYPE_COLUMN = "Connector type"; + private static final String VERSION_COLUMN = "Version"; + private static final String GIVEN_NAME_COLUMN = "Given name"; + private static final String FAMILY_NAME_COLUMN = "Family name"; + private static final String FULL_NAME_COLUMN = "Full name"; + private static final String EMAIL_COLUMN = "Email"; + private static final String ACCOUNTS_COLUMN = "Accounts"; + private static final String DISPLAY_NAME_COLUMN = "Display name"; + private static final String DESCRIPTION_COLUMN = "Description"; + private static final String IDENTIFIER_COLUMN = "Identifier"; + private static final String CATEGORY_COLUMN = "Category"; + private static final String OBJECT_REFERENCE_COLUMN = "Object reference"; + private static final String EXECUTION_COLUMN = "Execution"; + private static final String EXECUTING_AT_COLUMN = "Executing at"; + private static final String PROGRES_COLUMN = "Progress"; + private static final String CURRENT_RUN_TIME_COLUMN = "Current run time"; + private static final String SCHEDULED_TO_START_AGAIN_COLUMN = "Scheduled to start again"; + private static final QName CUSTOM = new QName("custom"); + + @Autowired + private ExpressionFactory expressionFactory; + @Autowired + private Clock clock; + @Autowired + private ModelInteractionService modelInteractionService; + @Autowired + private TaskManager taskManager; + @Autowired + private AuditService auditService; + @Autowired + private ModelService modelService; + @Autowired + private PrismContext prismContext; + @Autowired + @Qualifier("modelObjectResolver") + private ObjectResolver objectResolver; + + private static LinkedHashMap, LinkedHashMap> columnDef; + private static Set headsOfWidget; + private static Set headsOfAuditEventRecords; + + static { + columnDef = new LinkedHashMap, LinkedHashMap>() { + private static final long serialVersionUID = 1L; + { + put(ResourceType.class, new LinkedHashMap() { + private static final long serialVersionUID = 1L; + { + put(NAME_COLUMN, ResourceType.F_NAME); + put(CONNECTOR_TYPE_COLUMN, + ItemPath.create(ResourceType.F_CONNECTOR_REF, ConnectorType.F_CONNECTOR_TYPE)); + put(VERSION_COLUMN, + ItemPath.create(ResourceType.F_CONNECTOR_REF, ConnectorType.F_CONNECTOR_VERSION)); + } + }); + + put(UserType.class, new LinkedHashMap() { + private static final long serialVersionUID = 1L; + { + put(NAME_COLUMN, UserType.F_NAME); + put(GIVEN_NAME_COLUMN, UserType.F_GIVEN_NAME); + put(FAMILY_NAME_COLUMN, UserType.F_FAMILY_NAME); + put(FULL_NAME_COLUMN, UserType.F_FULL_NAME); + put(EMAIL_COLUMN, UserType.F_EMAIL_ADDRESS); + put(ACCOUNTS_COLUMN, ItemPath.create(AbstractRoleType.F_LINK_REF, CUSTOM)); + } + }); + + put(AbstractRoleType.class, new LinkedHashMap() { + private static final long serialVersionUID = 1L; + { + put(NAME_COLUMN, AbstractRoleType.F_NAME); + put(DISPLAY_NAME_COLUMN, AbstractRoleType.F_DISPLAY_NAME); + put(DESCRIPTION_COLUMN, AbstractRoleType.F_DESCRIPTION); + put(IDENTIFIER_COLUMN, AbstractRoleType.F_IDENTIFIER); + put(ACCOUNTS_COLUMN, ItemPath.create(AbstractRoleType.F_LINK_REF, CUSTOM)); + } + }); + + put(TaskType.class, new LinkedHashMap() { + private static final long serialVersionUID = 1L; + { + put(NAME_COLUMN, TaskType.F_NAME); + put(CATEGORY_COLUMN, TaskType.F_CATEGORY); + put(OBJECT_REFERENCE_COLUMN, TaskType.F_OBJECT_REF); + put(EXECUTION_COLUMN, TaskType.F_EXECUTION_STATUS); + put(EXECUTING_AT_COLUMN, TaskType.F_NODE_AS_OBSERVED); + put(PROGRES_COLUMN, TaskType.F_PROGRESS); + put(CURRENT_RUN_TIME_COLUMN, ItemPath.create(CUSTOM)); +// put(SCHEDULED_TO_START_AGAIN_COLUMN, ItemPath.create(CUSTOM)); + put(STATUS_COLUMN, TaskType.F_RESULT_STATUS); + } + }); + } + + }; + + headsOfWidget = new LinkedHashSet() { + { + add(LABEL_COLUMN); + add(NUMBER_COLUMN); + add(STATUS_COLUMN); + } + }; + + headsOfAuditEventRecords = new LinkedHashSet() { + { + add(TIME_COLUMN); + add(INITIATOR_COLUMN); + add(EVENT_STAGE_COLUMN); + add(EVENT_TYPE_COLUMN); + add(TARGET_COLUMN); + add(TARGET_OWNER_COLUMN); + add(CHANNEL_COLUMN); + add(OUTCOME_COLUMN); + } + }; + } + + @Override + protected void initialize() { + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Registering with taskManager as a handler for " + REPORT_HTML_CREATE_TASK_URI); } - return new HTMLElement("tr").setChildElements(childElements).toHTMLFormat(); + taskManager.registerHandler(REPORT_HTML_CREATE_TASK_URI, this); } - - private String createTBody(Task task) { - StringBuilder sb = new StringBuilder(); - List heads = getHead(); - for(Map value : getBody(task, task.getResult())) { - List childElementsOfTr = new ArrayList(); - for(String head: heads) { - HTMLElement div = value.get(head); - childElementsOfTr.add(new HTMLElement("td").addChildElement(div).setStyle("width: 10%;")); + + @Override + public TaskRunResult run(RunningTask task, TaskPartitionDefinitionType partition) { + OperationResult parentResult = task.getResult(); + OperationResult result = parentResult + .createSubresult(ReportHTMLCreateTaskHandler.class.getSimpleName() + ".run"); + + TaskRunResult runResult = new TaskRunResult(); + runResult.setOperationResult(result); + + super.recordProgress(task, 0, result); + try { + ReportType parentReport = objectResolver.resolve(task.getObjectRef(), ReportType.class, null, + "resolving report", task, result); + + if (parentReport.getReportEngine() == null) { + throw new IllegalArgumentException("Report Object doesn't have ReportEngine attribute"); + } + if (parentReport.getReportEngine().equals(ReportEngineSelectionType.JASPER)) { + parentReport.setExport(ExportType.HTML); + return super.run(task, partition); + + } else if (parentReport.getReportEngine().equals(ReportEngineSelectionType.DASHBOARD)) { + + if (parentReport.getDashboard() != null && parentReport.getDashboard().getDashboardRef() != null) { + ObjectReferenceType ref = parentReport.getDashboard().getDashboardRef(); + Class type = prismContext.getSchemaRegistry().determineClassForType(ref.getType()); + Task taskSearchDashboard = taskManager.createTaskInstance("Search dashboard"); + DashboardType dashboard = (DashboardType) modelService + .getObject(type, ref.getOid(), null, taskSearchDashboard, taskSearchDashboard.getResult()) + .asObjectable(); + String style = ""; + ClassLoader classLoader = getClass().getClassLoader(); + InputStream in = classLoader.getResourceAsStream(REPORT_CSS_STYLE_FILE_NAME); + byte[] data = IOUtils.toByteArray(in); + style = new String(data, Charset.defaultCharset()); + + String reportFilePath = getDestinationFileName(parentReport); + FileUtils.writeByteArrayToFile(new File(reportFilePath), getBody(dashboard, style).getBytes()); + super.saveReportOutputType(reportFilePath, parentReport, task, result); + LOGGER.trace("create report output type : {}", reportFilePath); + + if (parentReport.getPostReportScript() != null) { + super.processPostReportScript(parentReport, reportFilePath, task, result); + } + result.computeStatus(); + } else { + LOGGER.error("Dashboard or DashboardRef is null"); + throw new IllegalArgumentException("Dashboard or DashboardRef is null"); + } + } - sb.append(new HTMLElement("tr").setChildElements(childElementsOfTr).toHTMLFormat()); + } catch (Exception ex) { + LOGGER.error("CreateReport: {}", ex.getMessage(), ex); + result.recordFatalError(ex.getMessage(), ex); + runResult.setRunResultStatus(TaskRunResultStatus.PERMANENT_ERROR); + return runResult; } - return sb.toString(); + + // This "run" is finished. But the task goes on ... + runResult.setRunResultStatus(TaskRunResultStatus.FINISHED); + LOGGER.trace("CreateReportTaskHandler.run stopping"); + return runResult; } - private List getHead(){ - List heads = new ArrayList<>(); - heads.add("Label"); - heads.add("Number"); - heads.add("Status"); - - return heads; - } - - private List> getBody(Task task, OperationResult parentResult){ - List> body = new ArrayList<>(); - Map resources = new HashMap(); - - resources.put("Label", new HTMLElement("div").setText("Resources")); - String number = getNumber(ResourceType.class, - Arrays.asList(ResourceType.F_OPERATIONAL_STATE, OperationalStateType.F_LAST_AVAILABILITY_STATUS), - AvailabilityStatusType.UP, false, task, parentResult); - resources.put("Number", new HTMLElement("div").setText(number + " up")); - HTMLElement element = new HTMLElement("div").setStyle("width: 100%; height: 20px;"); - setStatusColor(number, element); - resources.put("Status", element); - body.add(resources); - - Map tasks = new HashMap(); - tasks.put("Label", new HTMLElement("div").setText("Tasks")); - number = getNumber(TaskType.class, - Arrays.asList(TaskType.F_EXECUTION_STATUS), - TaskExecutionStatusType.RUNNABLE, false, task, parentResult); - tasks.put("Number", new HTMLElement("div").setText(number + " active")); - element = new HTMLElement("div").setStyle("width: 100%; height: 20px;"); - setStatusColor(number, element); - tasks.put("Status", element); - body.add(tasks); - - Map modifications = new HashMap(); - modifications.put("Label", new HTMLElement("div").setText("Modifications")); - int total = listModificationsRecords(false).size(); - int active = listModificationsRecords(true).size(); - number = formatPercentage(total, active) + " %"; - modifications.put("Number", new HTMLElement("div").setText(number + " success")); - element = new HTMLElement("div").setStyle("width: 100%; height: 20px;"); - setStatusColor(total, active, false, element); - modifications.put("Status", element); - body.add(modifications); - - Map errors = new HashMap(); - errors.put("Label", new HTMLElement("div").setText("Errors")); - total = listAllOperationsRecords().size(); - active = listErrorsRecords().size(); - number = formatPercentage(total, active) + " %"; - errors.put("Number", new HTMLElement("div").setText(number + " failed")); - element = new HTMLElement("div").setStyle("width: 100%; height: 20px;"); - setStatusColor(total, active, true, element); - errors.put("Status", element); - body.add(errors); - - return body; - } - - private void setStatusColor(int totalCount, int activeCount, boolean zeroIsGood, HTMLElement element) { - if((zeroIsGood && activeCount == 0) || (totalCount == activeCount)) { - element.setClasses("object-access-bg"); - return; - } - element.setClasses("object-failed-bg"); + private String getBody(DashboardType dashboard, String cssStyle) { + StringBuilder body = new StringBuilder(); + body.append("
"); + + ContainerTag widgetTable = createTable(); + widgetTable.with(createTHead(getHeadsOfWidget())); + + ContainerTag widgetTBody = TagCreator.tbody(); + List tableboxesFromWidgets = new ArrayList(); + for (DashboardWidgetType widget : dashboard.getWidget()) { + DashboardWidget widgetData = DashboardUtils.createWidgetData(widget, modelService, taskManager, + expressionFactory, auditService, clock, modelInteractionService); + widgetTBody.with(createTBodyRow(widgetData)); + ContainerTag tableBox = createTableBoxForWidget(widgetData); + if (tableBox != null) { + tableboxesFromWidgets.add(tableBox); + } + } + widgetTable.with(widgetTBody); + + body.append(createTableBox(widgetTable, "Widgets").render()); + appendSpace(body); + tableboxesFromWidgets.forEach(table -> { + body.append(table.render()); + appendSpace(body); + }); + body.append(""); } - - private String getNumber(Class type, List items, Object eqObject, boolean isPercentage, Task task, OperationResult parentResult){ - - Integer total = 0; - Integer active = 0; - try { - total = modelService.countObjects(type, null, null, task, parentResult); - ObjectQuery query = prismContext.queryFor(type) - .item((QName[])items.toArray()).eq(eqObject) - .build(); - if(total == null) { - total = 0; - } - - active = modelService.countObjects(type, query, null, task, parentResult); - if(active == null) { - active = 0; - } - } catch (SchemaException | ObjectNotFoundException | SecurityViolationException | ConfigurationException - | CommunicationException | ExpressionEvaluationException e) { - return "ERROR: "+e.getMessage(); + + private ContainerTag createTableBoxForWidget(DashboardWidget widgetData) { + DashboardWidgetType widget = widgetData.getWidget(); + if (widget == null) { + throw new IllegalArgumentException("Widget in DashboardWidget is null"); } - - if(isPercentage) { - return formatPercentage(total, active) + " %"; - } - - return active + "/" + total; - } - - private String formatPercentage(int totalItems, int actualItems) { - float percentage = (totalItems==0 ? 0 : actualItems*100.0f/totalItems); - String format = "%.0f"; - - if(percentage < 100.0f && percentage % 10 != 0 && ((percentage % 10) % 1) != 0) { - format = "%.1f"; - } - return String.format(format, percentage); - } - - private List listModificationsRecords(boolean isSuccess){ - Map parameters = new HashedMap(); - List conditions = new ArrayList<>(); - conditions.add("aer.eventType = :auditEventType"); - parameters.put("auditEventType", AuditEventTypeType.MODIFY_OBJECT); - - if(isSuccess){ - conditions.add("aer.outcome = :outcome"); - parameters.put("outcome", OperationResultStatusType.SUCCESS); + DashboardWidgetSourceTypeType sourceType = DashboardUtils.getSourceType(widget); + DashboardWidgetPresentationType presentation = widget.getPresentation(); + switch (sourceType) { + case OBJECT_COLLECTION: + if (!DashboardUtils.isDataFieldsOfPresentationNullOrEmpty(presentation)) { + ObjectCollectionType collection = DashboardUtils.getObjectCollectionType(widget, taskManager, + prismContext, modelService); + List> values = DashboardUtils.searchObjectFromCollection(collection, true, + prismContext, taskManager, modelService); + if (values == null || values.isEmpty()) { + return null; + } + Class type = (Class) prismContext.getSchemaRegistry() + .getCompileTimeClassForObjectType(collection.getType()); + HashMap columns = getColumnsForType(type); + if (columns == null) { + LOGGER.error("Couldn't create table for objects with class {}", type.getName()); + } + ContainerTag table = createTable(); + table.with(createTHead(columns.keySet())); + ContainerTag tBody = TagCreator.tbody(); + values.forEach(value -> { + ContainerTag tr = TagCreator.tr(); + columns.keySet().forEach(column -> { + tr.with(TagCreator + .th(TagCreator.div(getRealValueAsString(column, value, columns.get(column))))); + }); + tBody.with(tr); + }); + table.with(tBody); + return createTableBox(table, widgetData.getLabel()); + } + break; + case AUDIT_SEARCH: + if (!DashboardUtils.isDataFieldsOfPresentationNullOrEmpty(presentation)) { + Map parameters = new HashMap(); + + ObjectCollectionType collection = DashboardUtils.getObjectCollectionType(widget, taskManager, + prismContext, modelService); + String query = DashboardUtils + .getQueryForListRecords(DashboardUtils.createQuery(collection, parameters, false, clock)); + List records = auditService.listRecords(query, parameters); + if (records == null || records.isEmpty()) { + return null; + } + + List auditRecordList = new ArrayList<>(); + for (AuditEventRecord record : records) { + auditRecordList.add(record.createAuditEventRecordType()); + } + + ContainerTag table = createTable(); + table.with(createTHead(getHeadsOfAuditEventRecords())); + ContainerTag tBody = TagCreator.tbody(); + auditRecordList.forEach(record -> { + ContainerTag tr = TagCreator.tr(); + getHeadsOfAuditEventRecords().forEach(column -> { + tr.with(TagCreator.th(TagCreator.div(getColumnForAuditEventRecord(column, record)))); + }); + tBody.with(tr); + }); + table.with(tBody); + return createTableBox(table, widgetData.getLabel()); + } + break; } - - return listAuditRecords(parameters, conditions); - } - - private List listErrorsRecords(){ - Map parameters = new HashedMap(); - List conditions = new ArrayList<>(); - conditions.add("aer.outcome = :outcome"); - parameters.put("outcome", OperationResultStatusType.FATAL_ERROR); - - return listAuditRecords(parameters, conditions); - } - - private List listAllOperationsRecords(){ - Map parameters = new HashedMap(); - List conditions = new ArrayList<>(); - return listAuditRecords(parameters, conditions); - } - - private List listAuditRecords(Map parameters, List conditions) { - - Date date = new Date(System.currentTimeMillis() - (24*3600000)); - conditions.add("aer.timestamp >= :from"); - parameters.put("from", XmlTypeConverter.createXMLGregorianCalendar(date)); - conditions.add("aer.eventStage = :auditStageType"); - parameters.put("auditStageType", AuditEventStageType.EXECUTION); - - String query = "from RAuditEventRecord as aer"; - if (!conditions.isEmpty()) { - query += " where "; + return null; + } + + private String getColumnForAuditEventRecord(String column, AuditEventRecordType record) { + switch (column) { + case TIME_COLUMN: + SimpleDateFormat dateFormat = new SimpleDateFormat("EEEE, d. MMM yyyy HH:mm:ss", Locale.US); + return dateFormat.format(record.getTimestamp().toGregorianCalendar().getTime()); + case INITIATOR_COLUMN: + ObjectReferenceType initiatorRef = record.getInitiatorRef(); + return getObjectNameFromRef(initiatorRef); + case EVENT_STAGE_COLUMN: + return record.getEventStage() == null ? "" : record.getEventStage().toString(); + case EVENT_TYPE_COLUMN: + return record.getEventType() == null ? "" : record.getEventType().toString(); + case TARGET_COLUMN: + ObjectReferenceType targetRef = record.getTargetRef(); + return getObjectNameFromRef(targetRef); + case TARGET_OWNER_COLUMN: + ObjectReferenceType targetOwnerRef = record.getTargetOwnerRef(); + return getObjectNameFromRef(targetOwnerRef); + case CHANNEL_COLUMN: + + return record.getChannel() == null ? "" : QNameUtil.uriToQName(record.getChannel()).getLocalPart(); + case OUTCOME_COLUMN: + if (record.getOutcome() == null) { + return ""; + } + return record.getOutcome().toString(); } - - query += conditions.stream().collect(Collectors.joining(" and ")); - query += " order by aer.timestamp desc"; + return ""; + } - List auditRecords; - auditRecords = auditService.listRecords(query, parameters); - - if (auditRecords == null) { - auditRecords = new ArrayList<>(); + private String getObjectNameFromRef(Referencable ref) { + if (ref == null) { + return ""; + } + if (ref.getTargetName() != null && ref.getTargetName().getOrig() != null) { + return ref.getTargetName().getOrig(); } - List auditRecordList = new ArrayList<>(); - for (AuditEventRecord record : auditRecords){ - auditRecordList.add(record.createAuditEventRecordType()); + PrismObject object = getObjectFromReference(ref); + + if (object == null) { + return ref.getOid(); } - return auditRecordList; + + if (object.getName() == null || object.getName().getOrig() == null) { + return ""; + } + return object.getName().getOrig(); } - - private class HTMLElement { - - private String tag; - private List childElements = new ArrayList(); - private String text = ""; - private String style = ""; - private String classes = ""; - - public HTMLElement(String tag) { - this.tag = tag; + + private String getRealValueAsString(String nameOfColumn, PrismObject object, ItemPath itemPath) { + Iterator iterator = (Iterator) itemPath.getSegments().iterator(); + Item valueObject = object; + + while (iterator.hasNext()) { + QName name = iterator.next(); + if (QNameUtil.match(name, CUSTOM)) { + return getCustomValueForColumn(valueObject, nameOfColumn); + } + valueObject = (Item) valueObject.find(ItemPath.create(name)); + if (valueObject instanceof PrismProperty && iterator.hasNext()) { + throw new IllegalArgumentException("Found object is PrismProperty, but ItemPath isn't empty"); + } + if (valueObject instanceof PrismContainer && !iterator.hasNext()) { + throw new IllegalArgumentException("Found object is PrismContainer, but ItemPath is empty"); + } + if (valueObject instanceof PrismReference) { + Referencable ref = ((PrismReference) valueObject).getRealValue(); + if (!iterator.hasNext()) { + return getObjectNameFromRef(ref); + } + + valueObject = getObjectFromReference(ref); + } + if (valueObject == null) { + if(nameOfColumn.equals(ACCOUNTS_COLUMN)) { + return "0"; + } + return ""; + } } - - public HTMLElement setText(String text) { - this.text = StringEscapeUtils.unescapeHtml4(text); - return this; + return ((PrismProperty) valueObject).getRealValue().toString(); + } + + private String getCustomValueForColumn(Item valueObject, String nameOfColumn) { + switch (nameOfColumn) { + case ACCOUNTS_COLUMN: + if(!(valueObject instanceof PrismObject)){ + return ""; + } + return String.valueOf(((PrismObject)valueObject).getRealValues().size()); + case CURRENT_RUN_TIME_COLUMN: + if(!(valueObject instanceof PrismObject) + && !(((PrismObject)valueObject).getRealValue() instanceof TaskType)){ + return ""; + } + TaskType task = (TaskType)((PrismObject)valueObject).getRealValue(); + XMLGregorianCalendar timestapm = task.getCompletionTimestamp(); + if(timestapm != null && task.getExecutionStatus().equals(TaskExecutionStatusType.CLOSED)) { + SimpleDateFormat dateFormat = new SimpleDateFormat("EEEE, d. MMM yyyy HH:mm:ss", Locale.US); + return "closed at " + dateFormat.format(task.getCompletionTimestamp().toGregorianCalendar().getTime()); + } + return ""; + case SCHEDULED_TO_START_AGAIN_COLUMN: + return ""; } - - public HTMLElement setStyle(String style) { - this.style = StringEscapeUtils.unescapeHtml4(style); - return this; + return ""; + } + + private PrismObject getObjectFromReference(Referencable ref) { + Task task = taskManager.createTaskInstance("Get object"); + Class type = prismContext.getSchemaRegistry().determineClassForType(ref.getType()); + + if (ref.asReferenceValue().getObject() != null) { + return ref.asReferenceValue().getObject(); } - - public HTMLElement setClasses(String classes) { - this.classes = StringEscapeUtils.unescapeHtml4(classes); - return this; + + PrismObject object = null; + try { + object = modelService.getObject(type, ref.getOid(), null, task, task.getResult()); + } catch (Exception e) { + LOGGER.error("Couldn't get object from objectRef " + ref, e); } - - public HTMLElement setChildElements(List childElements) { - this.childElements = childElements; - return this; + return object; + } + + private ContainerTag createTable() { + return TagCreator.table().withClasses("table", "table-striped", "table-hover", "table-bordered"); + } + + private ContainerTag createTableBox(ContainerTag table, String nameOfTable) { + ContainerTag div = TagCreator.div().withClasses("box-body", "no-padding").with(TagCreator.h1(nameOfTable)) + .with(table); + return TagCreator.div().withClasses("box", "boxed-table").with(div); + } + + private ContainerTag createTHead(Set set) { + return TagCreator.thead(TagCreator.tr(TagCreator.each(set, + header -> TagCreator.th(TagCreator.div(TagCreator.span(header).withClass("sortableLabel")))))); + } + + private ContainerTag createTBodyRow(DashboardWidget data) { + return TagCreator.tr(TagCreator.each(getHeadsOfWidget(), header -> getContainerTagForWidgetHeader(header, data) + + )); + + } + + private ContainerTag getContainerTagForWidgetHeader(String header, DashboardWidget data) { + if (header.equals(LABEL_COLUMN)) { + ContainerTag div = TagCreator.div(data.getLabel()); + return TagCreator.th().with(div); + } + if (header.equals(NUMBER_COLUMN)) { + ContainerTag div = TagCreator.div(data.getNumberMessage()); + return TagCreator.th().with(div); + } + if (header.equals(STATUS_COLUMN)) { + ContainerTag div = TagCreator.div().withStyle("width: 100%; height: 20px; "); + ContainerTag th = TagCreator.th(); + addStatusColor(th, data.getDisplay()); + th.with(div); + return th; } - - public HTMLElement addChildElement(HTMLElement childElement) { - this.childElements.add(childElement); - return this; + return TagCreator.th(); + } + + private void addStatusColor(ContainerTag div, DisplayType display) { + if (display != null && StringUtils.isNoneBlank(display.getColor())) { + div.withStyle("background-color: " + display.getColor() + "; !important;"); } - - public String toHTMLFormat() { - StringBuilder sb = new StringBuilder("<" + tag + " style=\"" + style + "\" class=\"" + classes + "\">" + text); - - for(HTMLElement element : childElements) { - sb.append(element.toHTMLFormat()); - } - - sb.append(""); - return sb.toString(); - } - } - - @Override - protected ExportType getExport(ReportType report) { - return ExportType.HTML; - } - + + } + + private Set getHeadsOfWidget() { + return headsOfWidget; + } + + private static Set getHeadsOfAuditEventRecords() { + return headsOfAuditEventRecords; + } + + private static LinkedHashMap, LinkedHashMap> getColumnDef() { + return columnDef; + } + + private static LinkedHashMap getColumnsForType(Class type ) { + if(type.equals(RoleType.class) + || type.equals(OrgType.class) + || type.equals(ServiceType.class)) { + return getColumnDef().get(AbstractRoleType.class); + } + return getColumnDef().get(type); + } + + @Override + protected ExportType getExport(ReportType report) { + return ExportType.HTML; + } + } diff --git a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportJasperCreateTaskHandler.java b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportJasperCreateTaskHandler.java index 577327471ad..017def389b7 100644 --- a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportJasperCreateTaskHandler.java +++ b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportJasperCreateTaskHandler.java @@ -143,7 +143,7 @@ public class ReportJasperCreateTaskHandler implements TaskHandler { @Autowired private CommandLineScriptExecutor commandLineScriptExecutor; @PostConstruct - private void initialize() { + protected void initialize() { if (LOGGER.isTraceEnabled()) { LOGGER.trace("Registering with taskManager as a handler for " + REPORT_CREATE_TASK_URI); } diff --git a/model/report-impl/src/main/resources/admin-dashboard-report-template.html b/model/report-impl/src/main/resources/dashboard-report-style.css similarity index 80% rename from model/report-impl/src/main/resources/admin-dashboard-report-template.html rename to model/report-impl/src/main/resources/dashboard-report-style.css index 1cf1fcac4f5..c17e6b5d5e9 100644 --- a/model/report-impl/src/main/resources/admin-dashboard-report-template.html +++ b/model/report-impl/src/main/resources/dashboard-report-style.css @@ -1,9 +1,3 @@ - - - - - - -
-
- - - - - - - -
-
-
- -