Skip to content

Commit

Permalink
Modified IdChangePipe to accept nested literals as ids
Browse files Browse the repository at this point in the history
IdChangePipe now allows to specify a nested literal name (by separating
the entity names with dots such as "grandpa.parent.id_literal").
Additionally, a keepIdLiteral flag has been introduced to control
whether the id literal is kept in the output or not.
  • Loading branch information
cboehme committed Feb 28, 2014
1 parent 43c52c3 commit e81b230
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 35 deletions.
37 changes: 26 additions & 11 deletions src/main/java/org/culturegraph/mf/stream/pipe/IdChangePipe.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package org.culturegraph.mf.stream.pipe;

import org.culturegraph.mf.framework.DefaultStreamPipe;
import org.culturegraph.mf.framework.DefaultStreamReceiver;
import org.culturegraph.mf.framework.StreamReceiver;
import org.culturegraph.mf.framework.annotations.Description;
import org.culturegraph.mf.framework.annotations.In;
Expand All @@ -25,9 +26,9 @@
/**
* Changes the record id to the value of the _id literal if present in the
* record.
*
*
* @author Markus Michael Geipel
*
*
*/
@Description("By default changes the record id to the value of the '_id' literal (if present). Use the contructor to choose another literal as id source.")
@In(StreamReceiver.class)
Expand All @@ -36,18 +37,21 @@ public final class IdChangePipe extends DefaultStreamPipe<StreamReceiver> {

private String idName = StreamConstants.ID;
private final StreamBuffer streamBuffer = new StreamBuffer();
private final StreamFlattener streamFlattener = new StreamFlattener();
private final DefaultStreamReceiver dummyReceiver = new DefaultStreamReceiver();
private String currentIdentifier;
private String originalIdentifier;
private int depth;
private boolean keepIdless = true;
private boolean keepIdLiteral;

public IdChangePipe() {
super();
this(StreamConstants.ID);
}

public IdChangePipe(final String idName) {
super();
setIdName(idName);
streamFlattener.setReceiver(dummyReceiver);
}

public void setIdName(final String idName) {
Expand All @@ -58,12 +62,16 @@ public void setKeepIdless(final boolean keepIdless) {
this.keepIdless = keepIdless;
}

public void setKeepIdLiteral(final boolean keepIdLiteral) {
this.keepIdLiteral = keepIdLiteral;
}

@Override
public void startRecord(final String identifier) {
assert !isClosed();
currentIdentifier = null;
originalIdentifier = identifier;
depth = 0;
streamFlattener.startRecord(identifier);
}

@Override
Expand All @@ -79,28 +87,35 @@ public void endRecord() {
getReceiver().endRecord();
}
streamBuffer.clear();
streamFlattener.endRecord();
}

@Override
public void startEntity(final String name) {
streamBuffer.startEntity(name);
++depth;
streamFlattener.startEntity(name);
}

@Override
public void endEntity() {
streamBuffer.endEntity();
--depth;

streamFlattener.endEntity();
}

@Override
public void literal(final String name, final String value) {
if (depth == 0 && idName.equals(name)) {
String path = streamFlattener.getCurrentPath();
if (!path.isEmpty()) {
path += ".";
}
path += name;
if (idName.equals(path)) {
currentIdentifier = value;
} else {
streamBuffer.literal(name, value);
if (!keepIdLiteral) {
return;
}
}
streamBuffer.literal(name, value);
}

@Override
Expand Down
88 changes: 64 additions & 24 deletions src/test/java/org/culturegraph/mf/stream/pipe/IdChangePipeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

/**
* Tests for {@link IdChangePipe}.
*
*
* @author Christoph Böhme
*
*/
Expand All @@ -43,44 +43,42 @@ public final class IdChangePipeTest {
private static final String ENTITY = "En";
private static final String LITERAL_NAME = "Li";
private static final String LITERAL_VALUE = "Va";

private IdChangePipe idChangePipe;

@Mock
private StreamReceiver receiver;

@Before
public void setup() {
MockitoAnnotations.initMocks(this);
idChangePipe = new IdChangePipe();
idChangePipe.setReceiver(receiver);
}

@After
public void cleanup() {
idChangePipe.closeStream();
}

@Test
public void testShouldChangeIdsOfRecords() {
idChangePipe.startRecord(OLD_RECORD_ID1);
idChangePipe.literal(StreamConstants.ID, NEW_RECORD_ID1);
idChangePipe.endRecord();

idChangePipe.startRecord(OLD_RECORD_ID2);
idChangePipe.literal(StreamConstants.ID, NEW_RECORD_ID2);
idChangePipe.endRecord();

final InOrder ordered = inOrder(receiver);
ordered.verify(receiver).startRecord(NEW_RECORD_ID1);
//ordered.verify(receiver).literal(StreamConstants.ID, NEW_RECORD_ID1);
ordered.verify(receiver).endRecord();

ordered.verify(receiver).startRecord(NEW_RECORD_ID2);
//ordered.verify(receiver).literal(StreamConstants.ID, NEW_RECORD_ID2);
ordered.verify(receiver).endRecord();
}

@Test
public void testShouldKeepRecordsWithoutIdLiteral() {
idChangePipe.startRecord(OLD_RECORD_ID1);
Expand All @@ -89,13 +87,12 @@ public void testShouldKeepRecordsWithoutIdLiteral() {
idChangePipe.startRecord(OLD_RECORD_ID2);
idChangePipe.literal(StreamConstants.ID, NEW_RECORD_ID2);
idChangePipe.endRecord();

final InOrder ordered = inOrder(receiver);
ordered.verify(receiver).startRecord(OLD_RECORD_ID1);
ordered.verify(receiver).literal(LITERAL_NAME, LITERAL_VALUE);
ordered.verify(receiver).endRecord();
ordered.verify(receiver).startRecord(NEW_RECORD_ID2);
//ordered.verify(receiver).literal(StreamConstants.ID, NEW_RECORD_ID2);
ordered.verify(receiver).endRecord();
}

Expand All @@ -109,42 +106,85 @@ public void testShouldRemoveRecordsWithoutIdLiteral() {
idChangePipe.startRecord(OLD_RECORD_ID2);
idChangePipe.literal(StreamConstants.ID, NEW_RECORD_ID2);
idChangePipe.endRecord();

final InOrder ordered = inOrder(receiver);
ordered.verify(receiver).startRecord(NEW_RECORD_ID2);
//ordered.verify(receiver).literal(StreamConstants.ID, NEW_RECORD_ID2);
ordered.verify(receiver).endRecord();
verifyNoMoreInteractions(receiver);
}

@Test
public void testShouldNotUseNestedIdLiteralAsNewId() {
idChangePipe.startRecord(OLD_RECORD_ID1);
idChangePipe.startEntity(ENTITY);
idChangePipe.literal(StreamConstants.ID, NEW_RECORD_ID1);
idChangePipe.endEntity();
idChangePipe.endRecord();

final InOrder ordered = inOrder(receiver);
ordered.verify(receiver).startRecord(OLD_RECORD_ID1);
ordered.verify(receiver).startEntity(ENTITY);
ordered.verify(receiver).literal(StreamConstants.ID, NEW_RECORD_ID1);
ordered.verify(receiver).endEntity();
ordered.verify(receiver).endRecord();
}

@Test

@Test
public void testShouldAcceptFullPathAsNewId() {
idChangePipe.setIdName(ENTITY + "." + StreamConstants.ID);

idChangePipe.startRecord(OLD_RECORD_ID1);
idChangePipe.startEntity(ENTITY);
idChangePipe.literal(StreamConstants.ID, NEW_RECORD_ID1);
idChangePipe.endEntity();
idChangePipe.endRecord();

final InOrder ordered = inOrder(receiver);
ordered.verify(receiver).startRecord(NEW_RECORD_ID1);
ordered.verify(receiver).startEntity(ENTITY);
ordered.verify(receiver).endEntity();
ordered.verify(receiver).endRecord();
}

@Test
public void testShouldNotKeepIdLiteralByDefault() {
idChangePipe.setIdName(StreamConstants.ID);

idChangePipe.startRecord(OLD_RECORD_ID1);
idChangePipe.literal(StreamConstants.ID, NEW_RECORD_ID1);
idChangePipe.endRecord();

final InOrder ordered = inOrder(receiver);
ordered.verify(receiver).startRecord(NEW_RECORD_ID1);
ordered.verify(receiver).endRecord();
verifyNoMoreInteractions(receiver);
}

@Test
public void testShouldKeepIdLiteralIfConfigured() {
idChangePipe.setIdName(StreamConstants.ID);
idChangePipe.setKeepIdLiteral(true);

idChangePipe.startRecord(OLD_RECORD_ID1);
idChangePipe.literal(StreamConstants.ID, NEW_RECORD_ID1);
idChangePipe.endRecord();

final InOrder ordered = inOrder(receiver);
ordered.verify(receiver).startRecord(NEW_RECORD_ID1);
ordered.verify(receiver).literal(StreamConstants.ID, NEW_RECORD_ID1);
ordered.verify(receiver).endRecord();
}

@Test
public void testShouldUseLastIdLiteralAsNewId() {
idChangePipe.startRecord(OLD_RECORD_ID1);
idChangePipe.literal(StreamConstants.ID, NEW_RECORD_ID1);
idChangePipe.literal(StreamConstants.ID, NEW_RECORD_ID2);
idChangePipe.endRecord();

final InOrder ordered = inOrder(receiver);
ordered.verify(receiver).startRecord(NEW_RECORD_ID2);
//ordered.verify(receiver).literal(StreamConstants.ID, NEW_RECORD_ID1);
//ordered.verify(receiver).literal(StreamConstants.ID, NEW_RECORD_ID2);
ordered.verify(receiver).endRecord();
}

}

0 comments on commit e81b230

Please sign in to comment.