package com.constellio.app.modules.robots.ui.pages; import com.constellio.app.entities.schemasDisplay.MetadataDisplayConfig; import com.constellio.app.modules.rm.model.enums.CopyType; import com.constellio.app.modules.robots.model.RegisteredAction; import com.constellio.app.modules.robots.model.services.RobotsService; import com.constellio.app.modules.robots.model.wrappers.ActionParameters; import com.constellio.app.modules.robots.model.wrappers.Robot; import com.constellio.app.modules.robots.services.RobotsManager; import com.constellio.app.modules.robots.ui.components.actionParameters.DynamicParametersField.DynamicParametersPresenter; import com.constellio.app.modules.robots.ui.navigation.RobotViews; import com.constellio.app.services.schemasDisplay.SchemasDisplayManager; import com.constellio.app.ui.entities.MetadataVO; import com.constellio.app.ui.entities.RecordVO; import com.constellio.app.ui.entities.RecordVO.VIEW_MODE; import com.constellio.app.ui.entities.UserVO; import com.constellio.app.ui.framework.builders.MetadataToVOBuilder; import com.constellio.app.ui.framework.builders.RecordToVOBuilder; import com.constellio.app.ui.framework.components.OverridingMetadataFieldFactory.Choice; import com.constellio.app.ui.framework.components.OverridingMetadataFieldFactory.FieldOverridePresenter; import com.constellio.app.ui.framework.components.OverridingMetadataFieldFactory.OverrideMode; import com.constellio.app.ui.framework.data.SearchResultVODataProvider; import com.constellio.app.ui.pages.base.SchemaPresenterUtils; import com.constellio.app.ui.pages.search.AdvancedSearchCriteriaComponent.SearchCriteriaPresenter; import com.constellio.app.ui.pages.search.SearchPresenterService; import com.constellio.app.ui.pages.search.criteria.Criterion; import com.constellio.app.ui.params.ParamUtils; import com.constellio.data.dao.dto.records.FacetValue; import com.constellio.data.utils.ImpossibleRuntimeException; import com.constellio.model.entities.Language; import com.constellio.model.entities.Taxonomy; import com.constellio.model.entities.records.Record; import com.constellio.model.entities.records.Transaction; import com.constellio.model.entities.records.wrappers.User; import com.constellio.model.entities.schemas.Metadata; import com.constellio.model.entities.schemas.MetadataSchemaType; import com.constellio.model.entities.schemas.MetadataSchemasRuntimeException; import com.constellio.model.entities.schemas.MetadataValueType; import com.constellio.model.services.records.RecordServicesException; import com.constellio.model.services.records.RecordServicesException.ValidationException; import com.constellio.model.services.schemas.builders.CommonMetadataBuilder; import com.constellio.model.services.search.StatusFilter; import com.constellio.model.services.search.query.ReturnedMetadatasFilter; import com.constellio.model.services.search.query.logical.LogicalSearchQuery; import com.constellio.model.services.search.query.logical.condition.LogicalSearchCondition; import java.io.IOException; import java.util.*; import static com.constellio.app.ui.i18n.i18n.$; import static com.constellio.model.services.search.query.logical.LogicalSearchQueryOperators.from; public class AddEditRobotPresenter extends BaseRobotPresenter<AddEditRobotView> implements FieldOverridePresenter, SearchCriteriaPresenter, DynamicParametersPresenter { private static final String RUN_EXTRACTORS_ACTION = "runExtractorsAction"; private static final String PATH_PREFIX = "pathPrefix"; private static final String IN_TAXONOMY = "inTaxonomy"; private static final String PLAN = "plan"; private static final String DEFAULT_COPY_STATUS = "defaultCopyStatus"; public static final String ADD = "add"; public static final String EDIT = "edit"; private static final String ACTION = Robot.DEFAULT_SCHEMA + "_" + Robot.ACTION; private static final String SCHEMA_FILTER = Robot.DEFAULT_SCHEMA + "_" + Robot.SCHEMA_FILTER; private RecordToVOBuilder recordToVOBuilder = new RecordToVOBuilder(); private RecordVO robot; private RecordVO actionParameters; private String schemaFilter; private String pageMode; private String actionCode; transient SchemasDisplayManager schemasDisplayManager; transient SearchPresenterService searchPresenterService; public AddEditRobotPresenter(AddEditRobotView view) { super(view, Robot.DEFAULT_SCHEMA); init(); } private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); init(); } private void init() { searchPresenterService = new SearchPresenterService(collection, modelLayerFactory); schemasDisplayManager = appLayerFactory.getMetadataSchemasDisplayManager(); } public AddEditRobotPresenter forParams(String parameters) { Map<String, String> params = ParamUtils.getParamsMap(parameters); pageMode = params.get("pageMode"); if (isAddMode()) { robot = newRobot(params.get("parentId")); } else if (isEditMode()) { robot = loadRobot(params.get("robotId")); actionCode = robot.get(Robot.ACTION); actionParameters = loadActionParametersRecord(); } schemaFilter = robot.get(Robot.SCHEMA_FILTER); return this; } public RecordVO getRobot() { return robot; } public void saveButtonClicked(RecordVO recordVO) { Transaction transaction = new Transaction().setUser(getCurrentUser()); if (actionParameters != null) { transaction.add(toParametersRecord(actionParameters)); } transaction.add(toRecord(recordVO)); try { recordServices().execute(transaction); } catch (RecordServicesException e) { view.showErrorMessage(e.getMessage()); return; } view.navigate().to(RobotViews.class).robotConfiguration(recordVO.getId()); } public void backButtonClicked(RecordVO recordVO) { if (isAddMode()) { String parentId = recordVO.get(Robot.PARENT); if (parentId == null) { view.navigate().to(RobotViews.class).listRootRobots(); } else { view.navigate().to(RobotViews.class).robotConfiguration(parentId); } } else { view.navigate().to(RobotViews.class).robotConfiguration(recordVO.getId()); } } public boolean canEditSchemaFilter() { return isAddMode() && robot.get(Robot.PARENT) == null; } public void schemaFilterSelected(String schemaType) { this.schemaFilter = schemaType; view.setCriteriaSchema(schemaType); view.setAvailableActions(getActionChoices()); view.resetActionParameters(null); view.setActionParametersFieldEnabled(requiresActionParameters()); } public String getSchemaFilter() { return schemaFilter; } @Override public OverrideMode getOverride(String metadataCode) { switch (metadataCode) { case ACTION: case SCHEMA_FILTER: return OverrideMode.DROPDOWN; default: return OverrideMode.NONE; } } @Override public List<Choice> getChoices(String metadataCode) { switch (metadataCode) { case ACTION: return getActionChoices(); case SCHEMA_FILTER: return getSchemaFilterChoices(); default: throw new ImpossibleRuntimeException("BUG. No choices for metadata: " + metadataCode); } } public boolean canAutoExecute() { return robot.get(Robot.PARENT) == null; } @Override public void addCriterionRequested() { view.addEmptyCriterion(); } @Override public List<MetadataVO> getMetadataAllowedInCriteria() { MetadataToVOBuilder builder = new MetadataToVOBuilder(); MetadataSchemaType schemaType = schemaType(schemaFilter); List<FacetValue> schema_s = modelLayerFactory.newSearchServices().query(new LogicalSearchQuery() .setNumberOfRows(0).setCondition(from(schemaType).returnAll()).addFieldFacet("schema_s").filteredWithUser(getCurrentUser())).getFieldFacetValues("schema_s"); Set<String> metadataLocalCodes = new HashSet<>(); if(schema_s != null) { for(FacetValue facetValue: schema_s) { if(facetValue.getQuantity() > 0) { String schema = facetValue.getValue(); metadataLocalCodes.addAll(types().getSchema(schema).getMetadatas().toLocalCodesList()); } } } List<MetadataVO> result = new ArrayList<>(); result.add(builder.build(schemaType.getMetadataWithAtomicCode(CommonMetadataBuilder.PATH), view.getSessionContext())); for (Metadata metadata : schemaType.getAllMetadatas()) { if(!schemaType.hasSecurity() || metadataLocalCodes.contains(metadata.getLocalCode())) { MetadataDisplayConfig config = schemasDisplayManager().getMetadata(view.getCollection(), metadata.getCode()); if (config.isVisibleInAdvancedSearch() && metadata.isEnabled() && isMetadataVisibleForUser(metadata, getCurrentUser())) { result.add(builder.build(metadata, view.getSessionContext())); } } } return result; } private boolean isMetadataVisibleForUser(Metadata metadata, User currentUser) { if(MetadataValueType.REFERENCE.equals(metadata.getType())) { String referencedSchemaType = metadata.getAllowedReferences().getTypeWithAllowedSchemas(); Taxonomy taxonomy = appLayerFactory.getModelLayerFactory().getTaxonomiesManager().getTaxonomyFor(collection, referencedSchemaType); if(taxonomy != null) { List<String> taxonomyGroupIds = taxonomy.getGroupIds(); List<String> taxonomyUserIds = taxonomy.getUserIds(); List<String> userGroups = currentUser.getUserGroups(); for(String group: taxonomyGroupIds) { for(String userGroup: userGroups) { if(userGroup.equals(group)) { return true; } } } return (taxonomyGroupIds.isEmpty() && taxonomyUserIds.isEmpty()) || taxonomyUserIds.contains(currentUser.getId()); } else { return true; } } return true; } @Override public MetadataVO getMetadataVO(String metadataCode) { return presenterService().getMetadataVO(metadataCode, view.getSessionContext()); } public boolean isAddMode() { return ADD.equals(pageMode); } public boolean isEditMode() { return EDIT.equals(pageMode); } private RecordVO loadRobot(String robotId) { return recordToVOBuilder.build(getRecord(robotId), VIEW_MODE.FORM, view.getSessionContext()); } private RecordVO newRobot(String parentId) { Robot robot = new RobotsService(view.getCollection(), appLayerFactory).newRobot(parentId); return recordToVOBuilder.build(robot.getWrappedRecord(), VIEW_MODE.FORM, view.getSessionContext()); } private List<Choice> getSchemaFilterChoices() { List<Choice> choices = new ArrayList<>(); Language language = Language.withCode(view.getSessionContext().getCurrentLocale().getLanguage()); for (String code : manager().getSupportedSchemaTypes()) { choices.add(new Choice(code, schemaType(code).getLabel(language))); } return choices; } private List<Choice> getActionChoices() { List<Choice> choices = new ArrayList<>(); if (schemaFilter != null) { for (RegisteredAction action : manager().getRegisteredActionsFor(schemaFilter)) { if (!RUN_EXTRACTORS_ACTION.equals(action.getCode())) { choices.add(new Choice(action.getCode(), $("robot.action." + action.getCode()))); } } } return choices; } @Override public RecordVO getDynamicParametersRecord() { return actionParameters; } @Override public RecordVO newDynamicParametersRecord() { RegisteredAction action = manager().getActionFor(actionCode); String schemaCode = action.getParametersSchemaLocalCode(); ActionParameters actionParameters = robotSchemas().newActionParameters(schemaCode); initMetadataValue(actionParameters, DEFAULT_COPY_STATUS, CopyType.PRINCIPAL, false); initMetadataValue(actionParameters, IN_TAXONOMY, PLAN, true); try { Metadata m = actionParameters.getSchema().get(PATH_PREFIX); initMetadataValue(actionParameters, PATH_PREFIX, m.getDefaultValue(), true); } catch (MetadataSchemasRuntimeException.NoSuchMetadata e) { // Just ignore it : The metadata defaultCopyStatus doesn't appart to this scheme } return recordToVOBuilder.build(actionParameters.getWrappedRecord(), VIEW_MODE.FORM, view.getSessionContext()); } private <T> void initMetadataValue(ActionParameters actionParameters, String metadataCode, T value, boolean force) { try { Metadata metadata = actionParameters.getSchema().get(metadataCode); if (metadata != null && (force || actionParameters.get(metadata) == null)) { actionParameters.set(metadata, value); } } catch (MetadataSchemasRuntimeException.NoSuchMetadata e) { // Just ignore it : The metadata defaultCopyStatus doesn't appart to this scheme } } private RecordVO loadActionParametersRecord() { String id = robot.get(Robot.ACTION_PARAMETERS); if (id == null) { return null; } else { return recordToVOBuilder.build(getRecord(id), VIEW_MODE.FORM, view.getSessionContext()); } } private Record toParametersRecord(RecordVO recordVO) { String schema = ActionParameters.SCHEMA_TYPE + "_" + getParametersSchemaLocalCode(); return new SchemaPresenterUtils(schema, view.getConstellioFactories(), view.getSessionContext()).toRecord(recordVO); } @SuppressWarnings("unused") @Override public boolean saveParametersRecord(RecordVO record) { try { recordServices().validateRecord(toParametersRecord(record)); } catch (ValidationException e) { view.showErrorMessage($(e.getErrors())); return false; } actionParameters = record; view.resetActionParameters(record); return true; } @Override public void cancelParametersEdit(RecordVO record) { // No need to actually do anything } public void actionSelected(String actionCode) { this.actionCode = actionCode; if (actionParameters != null && !actionParameters.getSchema().getCode().endsWith("_" + getParametersSchemaLocalCode())) { view.resetActionParameters(null); } view.setActionParametersFieldEnabled(requiresActionParameters()); } public boolean requiresActionParameters() { if (actionCode == null) { return false; } return getParametersSchemaLocalCode() != null; } private String getParametersSchemaLocalCode() { return manager().getActionFor(actionCode).getParametersSchemaLocalCode(); } public SearchResultVODataProvider getSearchResults(final List<Criterion> searchCriteria) { return new SearchResultVODataProvider(new RecordToVOBuilder(), appLayerFactory, view.getSessionContext()) { @Override protected LogicalSearchQuery getQuery() { return getSearchQuery(searchCriteria); } }; } protected LogicalSearchQuery getSearchQuery(List<Criterion> searchCriteria) { LogicalSearchQuery query = new LogicalSearchQuery(getSearchCondition(searchCriteria)).filteredWithUser(getCurrentUser()) .filteredByStatus(StatusFilter.ACTIVES).setPreferAnalyzedFields(true); query.setReturnedMetadatas( ReturnedMetadatasFilter.onlyFields(schemasDisplayManager.getReturnedFieldsForSearch(collection))); return query; } private LogicalSearchCondition getSearchCondition(List<Criterion> searchCriteria) { RobotsManager robotsManager = manager(); Robot tmpRobot = robotSchemas().wrapRobot(toRecord(robot)); tmpRobot.setSearchCriteria(searchCriteria); tmpRobot.setSchemaFilter(schemaFilter); return robotsManager.getResolveCondition(tmpRobot); } public UserVO getCurrentUserVO() { return view.getSessionContext().getCurrentUser(); } }