Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@

import java.awt.Component;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.Map;
import java.util.prefs.Preferences;

Expand All @@ -29,6 +31,8 @@
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;

import java.text.SimpleDateFormat;

import org.apache.commons.lang3.StringUtils;
import org.jdesktop.swingx.decorator.HighlighterFactory;

Expand Down Expand Up @@ -510,6 +514,81 @@ public Boolean hasAdvancedCriteria() {
return hasAdvancedCriteria;
}

public void applyFilter(MessageFilter messageFilter) {
stopEditing();
resetSelections();

if (messageFilter == null) {
return;
}

ItemSelectionTableModel<Integer, String> connectorModel = ((ItemSelectionTableModel<Integer, String>) connectorTable.getModel());
DefaultTableModel contentSearchModel = ((DefaultTableModel) contentSearchTable.getModel());
DefaultTableModel metaDataSearchModel = ((DefaultTableModel) metaDataSearchTable.getModel());

List<Integer> includedMetaDataIds = messageFilter.getIncludedMetaDataIds();
List<Integer> excludedMetaDataIds = messageFilter.getExcludedMetaDataIds();

if (includedMetaDataIds != null) {
connectorModel.unselectAllKeys();
for (Integer metaDataId : includedMetaDataIds) {
connectorModel.selectKey(metaDataId);
}
} else if (excludedMetaDataIds != null) {
connectorModel.selectAllKeys();
for (int row = 0; row < connectorModel.getRowCount(); row++) {
Integer metaDataId = (Integer) connectorModel.getValueAt(row, ItemSelectionTableModel.KEY_COLUMN);
if (excludedMetaDataIds.contains(metaDataId)) {
connectorModel.setValueAt(Boolean.FALSE, row, ItemSelectionTableModel.CHECKBOX_COLUMN);
}
}
}

messageIdLowerField.setText(Objects.toString(messageFilter.getMinMessageId(), ""));
messageIdUpperField.setText(Objects.toString(messageFilter.getMaxMessageId(), ""));
originalIdLowerField.setText(Objects.toString(messageFilter.getOriginalIdLower(), ""));
originalIdUpperField.setText(Objects.toString(messageFilter.getOriginalIdUpper(), ""));
importIdLowerField.setText(Objects.toString(messageFilter.getImportIdLower(), ""));
importIdUpperField.setText(Objects.toString(messageFilter.getImportIdUpper(), ""));
serverIdField.setText(StringUtils.defaultString(messageFilter.getServerId()));
sendAttemptsLower.setValue((messageFilter.getSendAttemptsLower() == null) ? 0 : messageFilter.getSendAttemptsLower());
sendAttemptsUpper.setValue(Objects.toString(messageFilter.getSendAttemptsUpper(), ""));
attachmentCheckBox.setSelected(Boolean.TRUE.equals(messageFilter.getAttachment()));
errorCheckBox.setSelected(Boolean.TRUE.equals(messageFilter.getError()));

if (messageFilter.getContentSearch() != null) {
for (ContentSearchElement contentSearchElement : messageFilter.getContentSearch()) {
for (String search : contentSearchElement.getSearches()) {
contentSearchModel.addRow(new Object[] { ContentType.fromCode(contentSearchElement.getContentCode()), search });
}
}
}

if (messageFilter.getMetaDataSearch() != null) {
for (MetaDataSearchElement metaDataSearchElement : messageFilter.getMetaDataSearch()) {
if (cachedMetaDataColumns.containsKey(metaDataSearchElement.getColumnName())) {
metaDataSearchModel.addRow(new Object[] {
metaDataSearchElement.getColumnName(),
MetaDataSearchOperator.fromString(metaDataSearchElement.getOperator()),
formatMetaDataValue(metaDataSearchElement.getValue()),
Boolean.TRUE.equals(metaDataSearchElement.getIgnoreCase()) });
}
}
}
}

private String formatMetaDataValue(Object value) {
if (value == null) {
return "";
}

if (value instanceof Calendar calendar) {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime());
Comment thread
mgaffigan marked this conversation as resolved.
}

return String.valueOf(value);
}

private void stopEditing() {
// if the user had typed in a value in the content search table, close the cell editor so that any value that was entered will be included in the search
TableCellEditor cellEditor = contentSearchTable.getCellEditor();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// SPDX-License-Identifier: MPL-2.0
// SPDX-FileCopyrightText: 2025 Mitch Gaffigan

package com.mirth.connect.client.ui.browsers.message;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.mirth.connect.model.converters.ObjectXMLSerializer;
import com.mirth.connect.model.filters.MessageFilter;

class MessageBrowserRecentFilterStore {
private static final int MAX_RECENT_FILTERS = 10;
Comment thread
jonbartels marked this conversation as resolved.
private static final String RECENT_FILTERS_PREFERENCE_PREFIX = "messageBrowserRecentFilters.";
// TODO: Replace with a cross-session time-limited encrypted store
// (In-memory assuming text searches represent PHI)
private static final Map<String, String> RECENT_FILTERS_BY_CHANNEL = new ConcurrentHashMap<>();
private Logger logger = LogManager.getLogger(this.getClass());

private final String prefKey;

public MessageBrowserRecentFilterStore(String channelId) {
this.prefKey = RECENT_FILTERS_PREFERENCE_PREFIX + channelId;
}

public List<MessageFilter> getRecentFilters() {
try {
String serialized = RECENT_FILTERS_BY_CHANNEL.getOrDefault(prefKey, "");
if (serialized.isBlank()) return List.of();

var result = ObjectXMLSerializer.getInstance().deserializeList(serialized, MessageFilter.class);
if (result == null) return List.of();

return result;
} catch (Exception e) {
// Fail quietly if the stored filters cannot be deserialized for any reason.
logger.warn("Failed to deserialize recent message filters for key {}.", prefKey, e);
return List.of();
Comment thread
mgaffigan marked this conversation as resolved.
}
}

public void addRecentFilter(MessageFilter filter) {
if (filter == null) {
throw new IllegalArgumentException("Filter cannot be null");
}

var filters = new ArrayList<>(getRecentFilters());

// Remove then re-add to avoid duplicates
filters.remove(filter);
filters.add(0, filter);

// Trim to the maximum number of recent filters
if (filters.size() > MAX_RECENT_FILTERS) {
filters.subList(MAX_RECENT_FILTERS, filters.size()).clear();
}
Comment thread
jonbartels marked this conversation as resolved.

try {
RECENT_FILTERS_BY_CHANNEL.put(prefKey, ObjectXMLSerializer.getInstance().serialize(filters));
} catch (Exception e) {
logger.warn("Failed to serialize recent message filters for key {}.", prefKey, e);
}
}
}
Loading
Loading