Skip to content
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

Adding support to link a tld to a child IBDO for inheriting parameters #919

Closed
wants to merge 6 commits into from
Closed
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
32 changes: 32 additions & 0 deletions src/main/java/emissary/core/BaseDataObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ public class BaseDataObject implements Serializable, Cloneable, Remote, IBaseDat

final SafeUsageChecker safeUsageChecker = new SafeUsageChecker();

protected final IBaseDataObject tld;

protected enum DataState {
NO_DATA, CHANNEL_ONLY, BYTE_ARRAY_ONLY, BYTE_ARRAY_AND_CHANNEL
}
Expand Down Expand Up @@ -251,6 +253,7 @@ public void checkForUnsafeDataChanges() {
public BaseDataObject() {
this.theData = null;
setCreationTimestamp(Instant.now());
tld = null;
}

/**
Expand All @@ -264,6 +267,7 @@ public BaseDataObject(final byte[] newData, final String name) {
setData(newData);
setFilename(name);
setCreationTimestamp(Instant.now());
tld = null;
}

/**
Expand All @@ -288,6 +292,28 @@ public BaseDataObject(final byte[] newData, final String name, final String form
}
}

public BaseDataObject(final byte[] newData, final String name, @Nullable final String form, IBaseDataObject tld) {
setData(newData);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason not to use this(newData, name, form);? Do you not want the creation timestamp set??

setFilename(name);
if (form != null) {
pushCurrentForm(form);
}
this.tld = tld;
}

public BaseDataObject(final byte[] newData, final String name, @Nullable final String form, @Nullable final String fileType,
IBaseDataObject tld) {
setData(newData);
setFilename(name);
if (form != null) {
pushCurrentForm(form);
}
if (fileType != null) {
this.setFileType(fileType);
}
this.tld = tld;
}

/**
* Set the header byte array WARNING: this implementation uses the passed in array directly, no copy is made so the
* caller should not reuse the array.
Expand Down Expand Up @@ -1509,4 +1535,10 @@ public String getTransactionId() {
public void setTransactionId(String transactionId) {
this.transactionId = transactionId;
}

@Override
public IBaseDataObject getTld() {
return tld;
}

}
11 changes: 11 additions & 0 deletions src/main/java/emissary/core/DataObjectFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ public static IBaseDataObject getInstance(final byte[] payload, final String fil
return getInstance(payload, filename, fileTypeAndForm, fileTypeAndForm);
}

public static IBaseDataObject getInstance(final byte[] payload, final String filename, final String fileTypeAndForm, IBaseDataObject tld) {
final Object o = Factory.create(clazz, payload, filename, fileTypeAndForm, tld);
return (IBaseDataObject) o;
}

/**
* Get an instance of the configured DataObject impl with filename, form, and file type set
*
Expand All @@ -97,4 +102,10 @@ public static IBaseDataObject getInstance(final byte[] payload, final String fil
final Object o = Factory.create(clazz, payload, filename, form, fileType);
return (IBaseDataObject) o;
}

public static IBaseDataObject getInstance(final byte[] payload, final String filename, final String form, final String fileType,
IBaseDataObject tld) {
final Object o = Factory.create(clazz, payload, filename, form, fileType, tld);
return (IBaseDataObject) o;
}
}
8 changes: 8 additions & 0 deletions src/main/java/emissary/core/IBaseDataObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -928,4 +928,12 @@ enum MergePolicy {
* @param transactionId the unique identifier of the transaction
*/
void setTransactionId(String transactionId);

/**
* Return the Top level document or null if there is none for this IBaseDataObject
*
* @return The TLD IBaseDataObject
*/
IBaseDataObject getTld();

}
24 changes: 24 additions & 0 deletions src/main/java/emissary/core/IBaseDataObjectHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
Expand Down Expand Up @@ -260,4 +262,26 @@ public static byte[] findPreferredData(final IBaseDataObject payload, List<Strin

return payload.data();
}

/**
* Get the effective parameters for a given payload, considering parameters inherited from the parents
*
* @param payload Get parameters from this IBaseDataObject
* @param tldKeys A set of keys to inherit from the top level document if not already present in the child metadata
* @return The new Map containing the full set of parameters including ones inherited from the top level document
*/
public static Map<String, Collection<Object>> getCombinedTldParameters(IBaseDataObject payload, Set<String> tldKeys) {
IBaseDataObject tld = payload.getTld();
Map<String, Collection<Object>> effectiveParams = new HashMap<>(payload.getParameters());
if (tld != null && tldKeys != null) {
for (String key : tld.getParameterKeys()) {
// Set the specified parameter from the TLD if it's not already set in the child metadata
if (!effectiveParams.containsKey(key)) {
effectiveParams.put(key, tld.getParameter(key));
}
}
}

return effectiveParams;
}
}
57 changes: 57 additions & 0 deletions src/test/java/emissary/core/IBaseDataObjectHelperTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import emissary.parser.SessionParser;
import emissary.test.core.junit5.UnitTest;

import com.google.common.collect.LinkedListMultimap;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
Expand Down Expand Up @@ -426,4 +427,60 @@ void testFindPreferredData() {

assertEquals(view1Bytes, IBaseDataObjectHelper.findPreferredData(ibdo1, preferredViews));
}

@Test
void testGetCombinedTldParameters() {
IBaseDataObject child = new BaseDataObject(new byte[0], "foo", "UNKNOWN");
child.putParameter("k1", "v1");
child.putParameter("k2", "v2");

LinkedListMultimap<String, Object> expected = LinkedListMultimap.create();
expected.put("k1", "v1");
expected.put("k2", "v2");

// Null TLD and null key set
assertEquals(expected.asMap(), IBaseDataObjectHelper.getCombinedTldParameters(child, null));
// Null TLD with keyset
assertEquals(expected.asMap(), IBaseDataObjectHelper.getCombinedTldParameters(child, new HashSet<>(Arrays.asList("foo", "bar", "baz"))));


IBaseDataObject tld = new BaseDataObject();
tld.putParameter("k1", "p1");
tld.putParameter("k2", "p2");
tld.putParameter("k3", "p3");

child = new BaseDataObject(new byte[0], "foo", "UNKNOWN", tld);
child.putParameter("k1", "v1");
child.putParameter("k2", "v2");
child.putParameter("k4", "v4");

expected = LinkedListMultimap.create();
expected.put("k1", "v1");
expected.put("k2", "v2");
expected.put("k4", "v4");

// Null key set so inherit nothing
assertEquals(expected.asMap(), IBaseDataObjectHelper.getCombinedTldParameters(child, null));


tld = new BaseDataObject();
tld.putParameter("k1", "p1");
tld.putParameter("k2", "p2");
tld.putParameter("k3", "p3");

child = new BaseDataObject(new byte[0], "foo", "UNKNOWN", tld);
child.putParameter("k1", "v1");
child.putParameter("k2", "v2");
child.putParameter("k4", "v4");

expected = LinkedListMultimap.create();
expected.put("k1", "v1");
expected.put("k2", "v2");
expected.put("k3", "p3");
expected.put("k4", "v4");

// TLD linked and subset of keys specified including some that don't exist in the TLD
assertEquals(expected.asMap(),
IBaseDataObjectHelper.getCombinedTldParameters(child, new HashSet<>(Arrays.asList("k1", "k2", "k3", "k4", "k5"))));
}
}