Skip to content

Commit

Permalink
Remove IBaseDataObjectHelper.setPrivateFieldValue() method.
Browse files Browse the repository at this point in the history
  • Loading branch information
James Cover jdcove2 committed Jan 25, 2024
1 parent 2e6736d commit 3da0a4c
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 69 deletions.
39 changes: 8 additions & 31 deletions src/main/java/emissary/core/IBaseDataObjectHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.lang.reflect.Field;
import java.security.NoSuchAlgorithmException;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.regex.Pattern;
import javax.annotation.Nullable;

Expand All @@ -30,6 +30,12 @@ public final class IBaseDataObjectHelper {
*/
private static final Logger LOGGER = LoggerFactory.getLogger(IBaseDataObjectHelper.class);

private static class InternalIdBaseDataObject extends BaseDataObject {
private InternalIdBaseDataObject(final UUID internalId) {
this.internalId = internalId;
}
}

private IBaseDataObjectHelper() {}

/**
Expand All @@ -44,14 +50,13 @@ private IBaseDataObjectHelper() {}
public static IBaseDataObject clone(final IBaseDataObject iBaseDataObject, final boolean fullClone) {
Validate.notNull(iBaseDataObject, "Required: iBaseDataObject not null");

final BaseDataObject bdo = new BaseDataObject();
final BaseDataObject bdo = fullClone ? new InternalIdBaseDataObject(iBaseDataObject.getInternalId()) : new BaseDataObject();

final SeekableByteChannelFactory sbcf = iBaseDataObject.getChannelFactory();
if (sbcf != null) {
bdo.setChannelFactory(sbcf);
}

bdo.replaceCurrentForm(null);
final List<String> allCurrentForms = iBaseDataObject.getAllCurrentForms();
for (int i = 0; i < allCurrentForms.size(); i++) {
bdo.enqueueCurrentForm(allCurrentForms.get(i));
Expand All @@ -71,11 +76,6 @@ public static IBaseDataObject clone(final IBaseDataObject iBaseDataObject, final
}

if (fullClone) {
try {
setPrivateFieldValue(bdo, "internalId", iBaseDataObject.getInternalId());
} catch (IllegalAccessException | NoSuchFieldException e) {
// Ignore any problems setting the internal id.
}
final String processingError = iBaseDataObject.getProcessingError();
if (processingError != null) {
bdo.addProcessingError(processingError.substring(0, processingError.length() - 1));
Expand All @@ -98,29 +98,6 @@ public static IBaseDataObject clone(final IBaseDataObject iBaseDataObject, final
return bdo;
}

/**
* This method reflectively sets a private method that is not normally accessible. This method should only be used when
* the field must be set and there is no other way to do it. Ideally the class would be modified so that this method
* call would not be necessary.
*
* @param bdo the BaseDataObject to set the field on.
* @param fieldName the name of the field to be set.
* @param object the object that the field is to be set to.
* @throws IllegalAccessException if this {@code Field} object is enforcing Java language access control and the
* underlying field is either inaccessible or final.
* @throws NoSuchFieldException if a field with the specified name is not found.
*/
public static void setPrivateFieldValue(final BaseDataObject bdo, final String fieldName, final Object object)
throws IllegalAccessException, NoSuchFieldException {
Validate.notNull(bdo, "Required: bdo not null");
Validate.notNull(fieldName, "Required: fieldName not null");

final Field field = bdo.getClass().getDeclaredField(fieldName);

field.setAccessible(true); // NOSONAR intentional visibility change
field.set(bdo, object); // NOSONAR intentional visibility change
}

/**
* Used to propagate needed parent information to a sprouted child. NOTE: This is taken from
* emissary.place.MultiFileServerPlace.
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/emissary/core/IBaseDataObjectXmlHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,8 @@ private IBaseDataObjectXmlHelper() {}
* @param kff an existing Kff handler
* @return a typical BDO with the specified data
*/
public static IBaseDataObject createStandardInitialIbdo(final SeekableByteChannelFactory sbcf,
public static IBaseDataObject createStandardInitialIbdo(final IBaseDataObject ibdo, final SeekableByteChannelFactory sbcf,
final String classification, final String formAndFileType, final KffDataObjectHandler kff) {
final IBaseDataObject ibdo = new BaseDataObject();
final IBaseDataObject tempIbdo = new BaseDataObject();

// We want to return the ibdo with the data field equal to null. This can only
Expand Down
11 changes: 0 additions & 11 deletions src/test/java/emissary/core/IBaseDataObjectHelperTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import org.mockito.MockedStatic;
import org.mockito.Mockito;

import java.io.IOException;
Expand Down Expand Up @@ -37,7 +36,6 @@
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.any;

class IBaseDataObjectHelperTest extends UnitTest {

Expand Down Expand Up @@ -184,15 +182,6 @@ void testCloneFilename() {
@Test
void testCloneInternalId() {
verifyClone("getInternalId", ibdo1, IS_NOT_SAME, IS_NOT_EQUALS, EQUAL_AFTER_FULL_CLONE);
// Now assert that if an exception occurs, the IDs will differ
try (MockedStatic<IBaseDataObjectHelper> helper = Mockito.mockStatic(IBaseDataObjectHelper.class, Mockito.CALLS_REAL_METHODS)) {
helper.when(() -> IBaseDataObjectHelper.setPrivateFieldValue(any(), any(), any()))
.thenThrow(IllegalAccessException.class);

final IBaseDataObject cloneExceptionIbdo = IBaseDataObjectHelper.clone(ibdo1, EQUAL_AFTER_FULL_CLONE);
assertNotEquals(ibdo1.getInternalId(), cloneExceptionIbdo.getInternalId());
// IDs will differ if an exception occurs during setPrivateField
}
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ void testCreateStandardInitialIbdo() {
expectedIbdo.setFileType(formAndFileType);
expectedIbdo.setClassification(classification);

final IBaseDataObject actualIbdo = IBaseDataObjectXmlHelper.createStandardInitialIbdo(sbcf, classification,
final IBaseDataObject actualIbdo = IBaseDataObjectXmlHelper.createStandardInitialIbdo(new BaseDataObject(), sbcf, classification,
formAndFileType, kff);

IBaseDataObjectDiffHelper.diff(expectedIbdo, actualIbdo, differences, DiffCheckConfiguration.onlyCheckData());
Expand Down
16 changes: 14 additions & 2 deletions src/test/java/emissary/test/core/junit5/RegressionTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package emissary.test.core.junit5;

import emissary.core.BaseDataObject;
import emissary.core.IBaseDataObject;
import emissary.core.IBaseDataObjectHelper;
import emissary.core.IBaseDataObjectXmlCodecs;
Expand Down Expand Up @@ -71,7 +72,7 @@ protected boolean generateAnswers() {
*/
@ForOverride
protected IBaseDataObject getInitialIbdo(final String resource) {
return RegressionTestUtil.getInitialIbdoWithFormInFilename(resource, kff);
return RegressionTestUtil.getInitialIbdoWithFormInFilename(new ClearDataBaseDataObject(), resource, kff);
}

/**
Expand All @@ -85,7 +86,11 @@ protected IBaseDataObject getInitialIbdo(final String resource) {
*/
@ForOverride
protected void tweakInitialIbdoBeforeSerialisation(final String resource, final IBaseDataObject initialIbdo) {
RegressionTestUtil.setDataToNull(initialIbdo);
if (initialIbdo instanceof ClearDataBaseDataObject) {
((ClearDataBaseDataObject) initialIbdo).clearData();
} else {
fail("Didn't get an expected type of IBaseDataObject");
}
}

/**
Expand Down Expand Up @@ -236,6 +241,13 @@ private Optional<String> hashBytesIfNonPrintable(byte[] bytes) {
// Everything above can be overridden by extending classes to modify behaviour as they see fit.
// Below this point, methods should not be able to be overridden as they are inherently part of RegressionTest.

protected class ClearDataBaseDataObject extends BaseDataObject {
protected void clearData() {
theData = null;
seekableByteChannelFactory = null;
}
}

@ParameterizedTest
@MethodSource("data")
@Override
Expand Down
25 changes: 3 additions & 22 deletions src/test/java/emissary/test/core/junit5/RegressionTestUtil.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package emissary.test.core.junit5;

import emissary.core.BaseDataObject;
import emissary.core.DiffCheckConfiguration;
import emissary.core.IBaseDataObject;
import emissary.core.IBaseDataObjectHelper;
import emissary.core.IBaseDataObjectXmlCodecs;
import emissary.core.IBaseDataObjectXmlCodecs.ElementDecoders;
import emissary.core.IBaseDataObjectXmlCodecs.ElementEncoders;
Expand Down Expand Up @@ -303,24 +301,6 @@ public static String getInitialFormFromFilename(final String resource) {
}
}

/**
* Allow setting the internal data fields to null to avoid being included during serialisation.
*
* @param initialIbdo to null out
*/
public static void setDataToNull(final IBaseDataObject initialIbdo) {
try {
if (initialIbdo instanceof BaseDataObject) {
IBaseDataObjectHelper.setPrivateFieldValue((BaseDataObject) initialIbdo, "theData", null);
IBaseDataObjectHelper.setPrivateFieldValue((BaseDataObject) initialIbdo, "seekableByteChannelFactory", null);
} else {
fail("Didn't get an expected type of IBaseDataObject");
}
} catch (final IllegalAccessException | NoSuchFieldException e) {
fail("Couldn't null out data for BDO", e);
}
}

/**
* Simple/default way to provide the initial IBDO
*
Expand All @@ -329,13 +309,14 @@ public static void setDataToNull(final IBaseDataObject initialIbdo) {
* @param resource path to the dat file
* @return the initial IBDO
*/
public static IBaseDataObject getInitialIbdoWithFormInFilename(final String resource, final KffDataObjectHandler kff) {
public static IBaseDataObject getInitialIbdoWithFormInFilename(final IBaseDataObject ibdo, final String resource,
final KffDataObjectHandler kff) {
try {
final Path datFileUrl = Paths.get(new ResourceReader().getResource(resource).toURI());
final InitialFinalFormFormat datFile = new InitialFinalFormFormat(datFileUrl);
final SeekableByteChannelFactory sbcf = FileChannelFactory.create(datFile.getPath());
// Create a BDO for the data, and set the filename correctly
final IBaseDataObject initialIbdo = IBaseDataObjectXmlHelper.createStandardInitialIbdo(sbcf, "Classification",
final IBaseDataObject initialIbdo = IBaseDataObjectXmlHelper.createStandardInitialIbdo(ibdo, sbcf, "Classification",
datFile.getInitialForm(), kff);
initialIbdo.setChannelFactory(sbcf);
initialIbdo.setFilename(datFile.getOriginalFileName());
Expand Down

0 comments on commit 3da0a4c

Please sign in to comment.