package com.constellio.app.ui.pages.management.schemas.metadata; import static com.constellio.app.ui.i18n.i18n.$; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import com.constellio.app.modules.rm.wrappers.Folder; import com.constellio.model.services.schemas.builders.*; import com.vaadin.ui.UI; import org.apache.commons.lang.StringUtils; import com.constellio.app.entities.schemasDisplay.MetadataDisplayConfig; import com.constellio.app.entities.schemasDisplay.SchemaTypeDisplayConfig; import com.constellio.app.entities.schemasDisplay.SchemaTypesDisplayConfig; import com.constellio.app.entities.schemasDisplay.enums.MetadataDisplayType; import com.constellio.app.entities.schemasDisplay.enums.MetadataInputType; import com.constellio.app.services.schemasDisplay.SchemaTypesDisplayTransactionBuilder; import com.constellio.app.services.schemasDisplay.SchemasDisplayManager; import com.constellio.app.ui.application.NavigatorConfigurationService; import com.constellio.app.ui.entities.FormMetadataVO; import com.constellio.app.ui.entities.MetadataVO; import com.constellio.app.ui.framework.builders.MetadataToFormVOBuilder; import com.constellio.app.ui.pages.base.SingleSchemaBasePresenter; import com.constellio.app.ui.params.ParamUtils; import com.constellio.data.utils.comparators.AbstractTextComparator; import com.constellio.model.entities.CorePermissions; import com.constellio.model.entities.Language; import com.constellio.model.entities.Taxonomy; import com.constellio.model.entities.records.wrappers.Collection; import com.constellio.model.entities.records.wrappers.Event; import com.constellio.model.entities.records.wrappers.User; import com.constellio.model.entities.schemas.AllowedReferences; import com.constellio.model.entities.schemas.Metadata; import com.constellio.model.entities.schemas.MetadataSchemaType; import com.constellio.model.entities.schemas.MetadataSchemaTypes; import com.constellio.model.entities.schemas.MetadataSchemasRuntimeException; import com.constellio.model.entities.schemas.MetadataValueType; import com.constellio.model.entities.schemas.Schemas; import com.constellio.model.services.schemas.MetadataSchemasManager; import com.constellio.model.services.schemas.MetadataSchemasManagerException.OptimisticLocking; import com.constellio.model.services.schemas.SchemaUtils; import com.constellio.model.services.schemas.builders.MetadataBuilderRuntimeException.EssentialMetadataCannotBeDisabled; import com.constellio.model.services.schemas.builders.MetadataBuilderRuntimeException.EssentialMetadataInSummaryCannotBeDisabled; import org.vaadin.dialogs.ConfirmDialog; public class AddEditMetadataPresenter extends SingleSchemaBasePresenter<AddEditMetadataView> { private Map<String, String> parameters; private String metadataCode; public AddEditMetadataPresenter(AddEditMetadataView view) { super(view); } @Override protected boolean hasPageAccess(String params, User user) { return user.has(CorePermissions.MANAGE_METADATASCHEMAS).globally(); } public void setParameters(Map<String, String> params) { this.parameters = params; } public void setMetadataCode(String metadataCode) { this.metadataCode = metadataCode; } public FormMetadataVO getFormMetadataVO() { FormMetadataVO found = null; if (metadataCode == null || metadataCode.isEmpty()) { return found; } MetadataSchemaTypes types = modelLayerFactory.getMetadataSchemasManager().getSchemaTypes(collection); SchemasDisplayManager displayManager = appLayerFactory.getMetadataSchemasDisplayManager(); if (types != null) { Metadata metadata = types.getMetadata(metadataCode); MetadataToFormVOBuilder voBuilder = new MetadataToFormVOBuilder(view.getSessionContext()); found = voBuilder.build(metadata, displayManager, parameters.get("schemaTypeCode"), view.getSessionContext()); } return found; } public boolean isInherited(String metadataCode) { MetadataSchemasManager schemasManager = modelLayerFactory.getMetadataSchemasManager(); try { Metadata metadata = schemasManager.getSchemaTypes(collection).getMetadata(metadataCode); return metadata.inheritDefaultSchema(); } catch (MetadataSchemasRuntimeException.NoSuchMetadata e) { return false; } } public List<String> getMetadataTypesCode() { List<String> typeCodes = new ArrayList<>(); final Map<String, String> typeCodesAndLabels = new HashMap<>(); for (MetadataSchemaType type : modelLayerFactory.getMetadataSchemasManager().getSchemaTypes(collection).getSchemaTypes()) { if (this.isAllowedReferenceType(type)) { typeCodes.add(type.getCode()); Language language = Language.withCode(view.getSessionContext().getCurrentLocale().getLanguage()); typeCodesAndLabels.put(type.getCode(), type.getLabel(language)); } } Collections.sort(typeCodes, new AbstractTextComparator<String>() { @Override protected String getText(String typeCode) { return typeCodesAndLabels.get(typeCode); } }); return typeCodes; } public String getMetadataTypesCaption(String code) { MetadataSchemaType type = modelLayerFactory.getMetadataSchemasManager().getSchemaTypes(collection).getSchemaType(code); return type.getLabel(Language.withCode(view.getSessionContext().getCurrentLocale().getLanguage())); } private boolean isAllowedReferenceType(MetadataSchemaType type) { MetadataSchemaTypes types = modelLayerFactory.getMetadataSchemasManager().getSchemaTypes(collection); MetadataSchemaType collectionType = types.getSchemaType(Collection.SCHEMA_TYPE); MetadataSchemaType eventType = types.getSchemaType(Event.SCHEMA_TYPE); return !(type.equals(collectionType) || type.equals(eventType)); } public void preSaveButtonClicked(final FormMetadataVO formMetadataVO, final boolean editMode) { final String schemaCode = getSchemaCode(); final MetadataSchemasManager schemasManager = modelLayerFactory.getMetadataSchemasManager(); final MetadataSchemaTypesBuilder types = schemasManager.modify(collection); final String code; boolean isSaveButtonClicked = false; final MetadataBuilder builder; if (!editMode) { builder = types.getSchema(schemaCode).create("USR" + formMetadataVO.getLocalcode()); builder.setMultivalue(formMetadataVO.isMultivalue()); builder.setType(formMetadataVO.getValueType()); builder.setSortable(formMetadataVO.isSortable()); builder.setSchemaAutocomplete(formMetadataVO.isAutocomplete()); builder.setSearchable(formMetadataVO.isSearchable()); if (formMetadataVO.getValueType().equals(MetadataValueType.REFERENCE)) { MetadataSchemaTypeBuilder refBuilder = types.getSchemaType(formMetadataVO.getReference()); Taxonomy taxonomy = modelLayerFactory.getTaxonomiesManager() .getTaxonomyFor(collection, formMetadataVO.getReference()); if (taxonomy != null) { builder.defineTaxonomyRelationshipToType(refBuilder); } else { builder.defineReferencesTo(refBuilder); } } code = schemaCode + "_" + "USR" + formMetadataVO.getLocalcode(); saveButtonClicked(formMetadataVO, editMode, schemaCode, schemasManager, types, code, false, builder); } else { builder = types.getSchema(schemaCode).get(formMetadataVO.getCode()); code = formMetadataVO.getCode(); if (!isInherited(code)) { final boolean reindexRequired = builder.isSortable() != formMetadataVO.isSortable() || builder.isSearchable() != formMetadataVO.isSearchable(); if (reindexRequired) { String confirmDialogMessage = $("AddEditMetadataPresenter.saveButton.sortable"); if (builder.isSearchable() != formMetadataVO.isSearchable()) { confirmDialogMessage = $("AddEditMetadataPresenter.saveButton.searchable"); } ConfirmDialog.show(UI.getCurrent(), $("AddEditMetadataPresenter.saveButton.title"), confirmDialogMessage, $("confirm"), $("cancel"), new ConfirmDialog.Listener() { @Override public void onClose(ConfirmDialog dialog) { if (dialog.isConfirmed()) { builder.setSchemaAutocomplete(formMetadataVO.isAutocomplete()); builder.setSearchable(formMetadataVO.isSearchable()); builder.setSortable(formMetadataVO.isSortable()); saveButtonClicked(formMetadataVO, editMode, schemaCode, schemasManager, types, code, reindexRequired, builder); } } }); } else { isSaveButtonClicked = true; } } else { isSaveButtonClicked = true; } if (isSaveButtonClicked) { saveButtonClicked(formMetadataVO, editMode, schemaCode, schemasManager, types, code, false, builder); } } } private void showConfirmDialogForReindexation(String title, String message) { } private void saveButtonClicked(FormMetadataVO formMetadataVO, boolean editMode, String schemaCode, MetadataSchemasManager schemasManager, MetadataSchemaTypesBuilder types, String code, boolean reindexRequired, MetadataBuilder builder) { builder.setDefaultValue(formMetadataVO.getDefaultValue()); builder.setInputMask(formMetadataVO.getInputMask()); builder.setEnabled(formMetadataVO.isEnabled()); for (Entry<String, String> entry : formMetadataVO.getLabels().entrySet()) { builder.addLabel(Language.withCode(entry.getKey()), entry.getValue()); } builder.setDefaultRequirement(formMetadataVO.isRequired()); builder.setDuplicable(formMetadataVO.isDuplicable()); if (isInherited(code)) { MetadataSchemaBuilder defaultSchemaBuilder = types .getSchema(schemaCode.substring(0, schemaCode.lastIndexOf('_')) + "_default"); String localCode = code.substring(code.lastIndexOf("_") + 1); if (defaultSchemaBuilder.hasMetadata(localCode)) { defaultSchemaBuilder.getMetadata(localCode).setInputMask(formMetadataVO.getInputMask()); } } try { schemasManager.saveUpdateSchemaTypes(types); } catch (OptimisticLocking optimistickLocking) { // TODO exception gestion throw new RuntimeException(optimistickLocking); } catch (EssentialMetadataCannotBeDisabled | EssentialMetadataInSummaryCannotBeDisabled e) { view.showErrorMessage($("AddEditMetadataView.essentialMetadataCannotBeDisabled")); return; } saveDisplayConfig(formMetadataVO, code, schemasManager, editMode); if (reindexRequired) { appLayerFactory.getSystemGlobalConfigsManager().setReindexingRequired(true); view.showMessage($("AddEditMetadataView.reindexRequired")); } String params = ParamUtils.addParams(NavigatorConfigurationService.ADD_EDIT_METADATA, parameters); view.navigate().to().listSchemaMetadata(params); } private void saveDisplayConfig(FormMetadataVO formMetadataVO, String code, MetadataSchemasManager schemasManager, boolean editMode) { SchemasDisplayManager displayManager = schemasDisplayManager(); MetadataInputType type = formMetadataVO.getInput(); MetadataDisplayType displayType = formMetadataVO.getDisplayType(); if (type == null) { type = MetadataInputType.FIELD; } if (displayType == null || (!MetadataInputType.CHECKBOXES.equals(type) && !MetadataInputType.RADIO_BUTTONS.equals(type))) { displayType = MetadataDisplayType.VERTICAL; } MetadataDisplayConfig displayConfig = displayManager.getMetadata(collection, code); if (displayConfig == null) { displayConfig = new MetadataDisplayConfig(collection, code, formMetadataVO.isAdvancedSearch(), type, formMetadataVO.isHighlight(), formMetadataVO.getMetadataGroup(), displayType); } else { displayConfig = displayConfig.withHighlightStatus(formMetadataVO.isHighlight()) .withVisibleInAdvancedSearchStatus(formMetadataVO.isAdvancedSearch()).withInputType(type) .withDisplayType(displayType).withMetadataGroup(formMetadataVO.getMetadataGroup()); } displayManager.saveMetadata(displayConfig); this.saveFacetDisplay(schemasManager, displayManager, code, formMetadataVO.isFacet()); if (!editMode) { this.saveSchemaDisplay(schemasManager, displayManager, code); } } private void saveSchemaDisplay(MetadataSchemasManager schemasManager, SchemasDisplayManager displayManager, String code) { SchemaTypesDisplayTransactionBuilder transactionBuilder = displayManager.newTransactionBuilderFor(collection); SchemaUtils schemaUtils = new SchemaUtils(); String schemaCode = schemaUtils.getSchemaCode(code); String typeCode = schemaUtils.getSchemaTypeCode(schemaCode); String localCode = schemaUtils.getLocalCode(code, schemaCode); List<String> hugeMetadatas = schemasManager.getSchemaTypes(collection).getSchema(schemaCode).getMetadatas() .onlyWithType(MetadataValueType.STRUCTURE, MetadataValueType.TEXT).toLocalCodesList(); transactionBuilder.in(typeCode) .addToDisplay(localCode) .beforeTheHugeCommentMetadata(); transactionBuilder.in(typeCode) .addToForm(localCode) .beforeMetadatas(hugeMetadatas); displayManager.execute(transactionBuilder.build()); } private void saveFacetDisplay(MetadataSchemasManager schemasManager, SchemasDisplayManager displayManager, String code, boolean isFacet) { Metadata metadata = schemasManager.getSchemaTypes(collection).getMetadata(code); boolean isGlobal = false; for (Metadata global : Schemas.getAllGlobalMetadatas()) { if (metadata.getCode().equals(global.getCode())) { isGlobal = true; break; } } SchemaTypesDisplayConfig typesConfig = displayManager.getTypes(collection); List<String> facets = new ArrayList<>(typesConfig.getFacetMetadataCodes()); if (isFacet) { if (isGlobal) { if (!facets.contains(metadata.getLocalCode())) { facets.add(metadata.getLocalCode()); } } else { if (!facets.contains(metadata.getCode())) { facets.add(metadata.getCode()); } } } else { if (facets.contains(metadata.getLocalCode())) { facets.remove(metadata.getLocalCode()); } else if (facets.contains(metadata.getCode())) { facets.remove(metadata.getCode()); } } typesConfig = typesConfig.withFacetMetadataCodes(facets); displayManager.saveTypes(typesConfig); } public List<String> getMetadataGroupList() { SchemaTypeDisplayConfig schemaConfig = schemasDisplayManager().getType(collection, parameters.get("schemaTypeCode")); return new ArrayList<>(schemaConfig.getMetadataGroup().keySet()); } public String getGroupLabel(String code) { SchemaTypeDisplayConfig schemaConfig = schemasDisplayManager().getType(collection, parameters.get("schemaTypeCode")); Language language = Language.withCode(view.getSessionContext().getCurrentLocale().getLanguage()); return schemaConfig.getMetadataGroup().get(code).get(language); } public void cancelButtonClicked() { String params = ParamUtils.addParams(NavigatorConfigurationService.ADD_EDIT_SCHEMA_METADATA, parameters); view.navigate().to().listSchemaMetadata(params); } public boolean isMetadataEnableStatusModifiable() { return metadataCode.isEmpty() || !getMetadata(metadataCode).isEssential(); } public boolean isMetadataRequiredStatusModifiable() { return metadataCode.isEmpty() || !getMetadata(metadataCode).isEssential() || getMetadata(metadataCode).hasSameCode(Schemas.LEGACY_ID); } public boolean isFolderMediumTypes() { return metadataCode.startsWith(Folder.SCHEMA_TYPE) && metadataCode.endsWith(Folder.MEDIUM_TYPES) ; } public void inputTypeValueChanged(FormMetadataVO formMetadataVO) { boolean noReferenceType = formMetadataVO.getValueType() == MetadataValueType.REFERENCE && StringUtils .isBlank(formMetadataVO.getReference()); if (!noReferenceType) { view.reloadForm(); } } public void displayTypeValueChanged() { view.reloadForm(); } public void valueTypeValueChanged() { view.reloadForm(); } public void multivalueValueChanged(FormMetadataVO formMetadataVO) { boolean noReferenceType = formMetadataVO.getValueType() == MetadataValueType.REFERENCE && StringUtils .isBlank(formMetadataVO.getReference()); if (!noReferenceType) { view.reloadForm(); } } public void refTypeValueChanged() { view.reloadForm(); } public MetadataVO getDefaultValueMetadataVO(FormMetadataVO formMetadataVO) { try { MetadataInputType inputType = formMetadataVO.getInput(); MetadataDisplayType displayType = formMetadataVO.getDisplayType(); if (formMetadataVO.getValueType() == MetadataValueType.REFERENCE) { inputType = MetadataInputType.LOOKUP; } if (!inputType.equals(MetadataInputType.CHECKBOXES) && !inputType.equals(MetadataInputType.RADIO_BUTTONS)){ displayType = MetadataDisplayType.VERTICAL; } MetadataVO metadataVO = new MetadataVO(formMetadataVO.getCode(), formMetadataVO.getValueType(), collection, formMetadataVO.getSchema(), formMetadataVO.isRequired(), formMetadataVO.isMultivalue(), false, new HashMap<Locale, String>(), null, new String[] {}, formMetadataVO.getReference(), inputType, displayType, new AllowedReferences(formMetadataVO.getReference(), null), formMetadataVO.getMetadataGroup(), formMetadataVO.getDefaultValue(), false); return metadataVO; } catch (Exception ex) { return null; } } public boolean isDefaultValuePossible(FormMetadataVO formMetadataVO) { MetadataValueType valueType = formMetadataVO.getValueType(); return valueType != null && !valueType.equals(MetadataValueType.CONTENT); } public boolean isMetadataSystemReserved() { return !metadataCode.isEmpty() && getMetadata(metadataCode).isSystemReserved(); } }