Skip to content

DestinationSet should implement java.util.Set #44

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
378 changes: 219 additions & 159 deletions server/src/com/mirth/connect/server/userutil/DestinationSet.java
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

/*
* Copyright (c) Mirth Corporation. All rights reserved.
*
Expand All @@ -7,162 +8,221 @@
* been included with this distribution in the LICENSE.txt file.
*/

package com.mirth.connect.server.userutil;

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.mozilla.javascript.Context;

import com.mirth.connect.donkey.server.Constants;
import com.mirth.connect.userutil.ImmutableConnectorMessage;

/**
* Utility class used in the preprocessor or source filter/transformer to prevent the message from
* being sent to specific destinations.
*/
public class DestinationSet {

private Map<String, Integer> destinationIdMap;
private Set<Integer> metaDataIds;

/**
* DestinationSet instances should NOT be constructed manually. The instance "destinationSet"
* provided in the scope should be used.
*
* @param connectorMessage
* The delegate ImmutableConnectorMessage object.
*/
public DestinationSet(ImmutableConnectorMessage connectorMessage) {
try {
if (connectorMessage.getSourceMap().containsKey(Constants.DESTINATION_SET_KEY)) {
this.destinationIdMap = connectorMessage.getDestinationIdMap();
this.metaDataIds = (Set<Integer>) connectorMessage.getSourceMap().get(Constants.DESTINATION_SET_KEY);
}
} catch (Exception e) {
}
}

/**
* Stop a destination from being processed for this message.
*
* @param metaDataIdOrConnectorName
* An integer representing the metaDataId of a destination connector, or the actual
* destination connector name.
* @return A boolean indicating whether at least one destination connector was actually removed
* from processing for this message.
*/
public boolean remove(Object metaDataIdOrConnectorName) {
if (metaDataIds != null) {
Integer metaDataId = convertToMetaDataId(metaDataIdOrConnectorName);

if (metaDataId != null) {
return metaDataIds.remove(metaDataId);
}
}

return false;
}

/**
* Stop a destination from being processed for this message.
*
* @param metaDataIdOrConnectorNames
* A collection of integers representing the metaDataId of a destination connectors,
* or the actual destination connector names. JavaScript arrays can be used.
* @return A boolean indicating whether at least one destination connector was actually removed
* from processing for this message.
*/
public boolean remove(Collection<Object> metaDataIdOrConnectorNames) {
boolean removed = false;

for (Object metaDataIdOrConnectorName : metaDataIdOrConnectorNames) {
if (remove(metaDataIdOrConnectorName)) {
removed = true;
}
}

return removed;
}

/**
* Stop all except one destination from being processed for this message.
*
* @param metaDataIdOrConnectorName
* An integer representing the metaDataId of a destination connector, or the actual
* destination connector name.
* @return A boolean indicating whether at least one destination connector was actually removed
* from processing for this message.
*/
public boolean removeAllExcept(Object metaDataIdOrConnectorName) {
if (metaDataIds != null) {
Integer metaDataId = convertToMetaDataId(metaDataIdOrConnectorName);

if (metaDataId != null) {
return metaDataIds.retainAll(Collections.singleton(metaDataId));
}
}

return false;
}

/**
* Stop all except one destination from being processed for this message.
*
* @param metaDataIdOrConnectorNames
* A collection of integers representing the metaDataId of a destination connectors,
* or the actual destination connector names. JavaScript arrays can be used.
* @return A boolean indicating whether at least one destination connector was actually removed
* from processing for this message.
*/
public boolean removeAllExcept(Collection<Object> metaDataIdOrConnectorNames) {
if (metaDataIds != null) {
Set<Integer> set = new HashSet<Integer>();

for (Object metaDataIdOrConnectorName : metaDataIdOrConnectorNames) {
Integer metaDataId = convertToMetaDataId(metaDataIdOrConnectorName);

if (metaDataId != null) {
set.add(metaDataId);
}
}

return metaDataIds.retainAll(set);
}

return false;
}

/**
* Stop all destinations from being processed for this message. This does NOT mark the source
* message as FILTERED.
*
* @return A boolean indicating whether at least one destination connector was actually removed
* from processing for this message.
*/
public boolean removeAll() {
if (metaDataIds != null && metaDataIds.size() > 0) {
metaDataIds.clear();
return true;
}

return false;
}

private Integer convertToMetaDataId(Object metaDataIdOrConnectorName) {
if (metaDataIdOrConnectorName != null) {
if (metaDataIdOrConnectorName instanceof Number) {
return ((Number) metaDataIdOrConnectorName).intValue();
} else if (metaDataIdOrConnectorName.getClass().getName().equals("org.mozilla.javascript.NativeNumber")) {
return (Integer) Context.jsToJava(metaDataIdOrConnectorName, int.class);
} else if (destinationIdMap != null) {
return destinationIdMap.get(metaDataIdOrConnectorName.toString());
}
}

return null;
}
}
package com.mirth.connect.server.userutil;

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import org.mozilla.javascript.Context;

import com.mirth.connect.donkey.server.Constants;
import com.mirth.connect.userutil.ImmutableConnectorMessage;

/**
* Utility class used in the preprocessor or source filter/transformer to prevent the message from
* being sent to specific destinations.
*/
public class DestinationSet implements Set<Integer> {

private Map<String, Integer> destinationIdMap = Collections.emptyMap();
private Set<Integer> metaDataIds;

/**
* DestinationSet instances should NOT be constructed manually. The instance "destinationSet"
* provided in the scope should be used.
*
* @param connectorMessage
* The delegate ImmutableConnectorMessage object.
*/
public DestinationSet(ImmutableConnectorMessage connectorMessage) {
try {
if (connectorMessage.getSourceMap().containsKey(Constants.DESTINATION_SET_KEY)) {
this.destinationIdMap = connectorMessage.getDestinationIdMap();
this.metaDataIds = (Set<Integer>) connectorMessage.getSourceMap().get(Constants.DESTINATION_SET_KEY);
}
} catch (Exception e) {
metaDataIds = new HashSet<>();
}
}

/**
* Stop a destination from being processed for this message.
*
* @param metaDataIdOrConnectorName
* An integer representing the metaDataId of a destination connector, or the actual
* destination connector name.
* @return A boolean indicating whether at least one destination connector was actually removed
* from processing for this message.
*/
public boolean remove(Object metaDataIdOrConnectorName) {
return remove(Collections.singleton(metaDataIdOrConnectorName));
}

/**
* Stop a destination from being processed for this message.
*
* @param metaDataIdOrConnectorNames
* A collection of integers representing the metaDataId of a destination connectors,
* or the actual destination connector names. JavaScript arrays can be used.
* @return A boolean indicating whether at least one destination connector was actually removed
* from processing for this message.
*/
public boolean remove(Collection<Object> metaDataIdOrConnectorNames) {
if(metaDataIdOrConnectorNames == null) { return false; }

return metaDataIdOrConnectorNames.stream()
.map(this::convertToMetaDataId)
.filter(Optional::isPresent)
.map(Optional::get)
.map(metaDataIds::remove)
.filter(Boolean::booleanValue)
.count() > 0;
}

/**
* Stop all except one destination from being processed for this message.
*
* @param metaDataIdOrConnectorName
* An integer representing the metaDataId of a destination connector, or the actual
* destination connector name.
* @return A boolean indicating whether at least one destination connector was actually removed
* from processing for this message.
*/
public boolean removeAllExcept(Object metaDataIdOrConnectorName) {
return removeAllExcept(Collections.singleton(metaDataIdOrConnectorName));
}

/**
* Stop all except one destination from being processed for this message.
*
* @param metaDataIdOrConnectorNames
* A collection of integers representing the metaDataId of a destination connectors,
* or the actual destination connector names. JavaScript arrays can be used.
* @return A boolean indicating whether at least one destination connector was actually removed
* from processing for this message.
*/
public boolean removeAllExcept(Collection<Object> metaDataIdOrConnectorNames) {
if(metaDataIdOrConnectorNames == null) { return false; }

Set<Integer> set = metaDataIdOrConnectorNames.stream()
.map(this::convertToMetaDataId)
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toSet());

return metaDataIds.retainAll(set);
}

/**
* Stop all destinations from being processed for this message. This does NOT mark the source
* message as FILTERED.
*
* @return A boolean indicating whether at least one destination connector was actually removed
* from processing for this message.
*/
public boolean removeAll() {
int origSize = size();
clear();
return origSize > 0;
}

private Optional<Integer> convertToMetaDataId(Object metaDataIdOrConnectorName) {
Integer result = null;

if (metaDataIdOrConnectorName != null) {
if (metaDataIdOrConnectorName instanceof Number) {
result = Integer.valueOf(((Number) metaDataIdOrConnectorName).intValue());
} else if (metaDataIdOrConnectorName.getClass().getName().equals("org.mozilla.javascript.NativeNumber")) {
result = (Integer) Context.jsToJava(metaDataIdOrConnectorName, int.class);
} else {
result = destinationIdMap.get(metaDataIdOrConnectorName.toString());
}
}

return Optional.ofNullable(result);
}

@Override
public int size() {
return metaDataIds.size();
}

@Override
public boolean isEmpty() {
return metaDataIds.isEmpty();
}

@Override
public boolean contains(Object metaDataIdOrConnectorName) {
Optional<Integer> m = convertToMetaDataId(metaDataIdOrConnectorName);

return m.isPresent() && metaDataIds.contains(m.get());
}

@Override
public Iterator<Integer> iterator() {
return Collections.unmodifiableSet(metaDataIds).iterator();
}

@Override
public Object[] toArray() {
return metaDataIds.toArray();
}

@Override
public <T> T[] toArray(T[] a) {
return metaDataIds.toArray(a);
}

@Override
public boolean add(Integer metaDataId) {
return metaDataId != null && metaDataIds.add(metaDataId);
}

@Override
public boolean containsAll(Collection<?> metaDataIdOrConnectorNames) {
if(metaDataIdOrConnectorNames == null) { return false; }

return metaDataIdOrConnectorNames.stream()
.map(this::contains)
.allMatch(Boolean::booleanValue);
}

@Override
public boolean addAll(Collection<? extends Integer> metaDataIdOrConnectorNames) {
boolean changed = false;

if(metaDataIdOrConnectorNames != null) {
for(Object item : metaDataIdOrConnectorNames) {
Optional<Integer> m = convertToMetaDataId(item);

if(m.isPresent() && metaDataIds.add(m.get())) {
changed = true;
}
}
}

return changed;
}

@Override
public boolean retainAll(Collection<?> metaDataIdOrConnectorNames) {
return removeAllExcept((Collection<Object>)metaDataIdOrConnectorNames);
}

@Override
public boolean removeAll(Collection<?> metaDataIdOrConnectorNames) {
return remove((Collection<Object>)metaDataIdOrConnectorNames);
}

@Override
public void clear() {
metaDataIds.clear();
}
}
Loading