Skip to content

Commit 04acdae

Browse files
committed
Merge #332 into oersi
2 parents 11982de + 8bf5bcb commit 04acdae

File tree

7 files changed

+220
-4
lines changed

7 files changed

+220
-4
lines changed

metafacture-biblio/src/main/java/org/metafacture/biblio/marc21/MarcXmlHandler.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,17 @@ public final class MarcXmlHandler extends DefaultXmlPipe<StreamReceiver> {
4545
private static final String LEADER = "leader";
4646
private static final String TYPE = "type";
4747
private String currentTag = "";
48+
private String namespace = NAMESPACE;
4849
private StringBuilder builder = new StringBuilder();
4950

51+
public void setNamespace(final String namespace) {
52+
this.namespace = namespace;
53+
}
54+
55+
private boolean checkNamespace(final String uri) {
56+
return namespace == null || namespace.equals(uri);
57+
}
58+
5059
@Override
5160
public void startElement(final String uri, final String localName, final String qName, final Attributes attributes)
5261
throws SAXException {
@@ -58,7 +67,7 @@ public void startElement(final String uri, final String localName, final String
5867
}else if(CONTROLFIELD.equals(localName)){
5968
builder = new StringBuilder();
6069
currentTag = attributes.getValue("tag");
61-
}else if(RECORD.equals(localName) && NAMESPACE.equals(uri)){
70+
}else if(RECORD.equals(localName) && checkNamespace(uri)){
6271
getReceiver().startRecord("");
6372
getReceiver().literal(TYPE, attributes.getValue(TYPE));
6473
}else if(LEADER.equals(localName)){
@@ -77,7 +86,7 @@ public void endElement(final String uri, final String localName, final String qN
7786
}else if(CONTROLFIELD.equals(localName)){
7887
getReceiver().literal(currentTag, builder.toString().trim());
7988

80-
}else if(RECORD.equals(localName) && NAMESPACE.equals(uri)){
89+
}else if(RECORD.equals(localName) && checkNamespace(uri)){
8190
getReceiver().endRecord();
8291

8392
}else if(LEADER.equals(localName)){

metafacture-biblio/src/test/java/org/metafacture/biblio/marc21/MarcXmlHandlerTest.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.metafacture.biblio.marc21;
1717

1818
import static org.mockito.Mockito.verify;
19+
import static org.mockito.Mockito.verifyNoMoreInteractions;
1920

2021
import org.junit.After;
2122
import org.junit.Before;
@@ -37,6 +38,8 @@ public final class MarcXmlHandlerTest {
3738
private static final String LEADER = "leader";
3839
private static final String CONTROLFIELD = "controlfield";
3940
private static final String NAMESPACE = "http://www.loc.gov/MARC21/slim";
41+
private static final String RECORD = "record";
42+
private static final String TYPE = "type";
4043

4144
private MarcXmlHandler marcXmlHandler;
4245

@@ -84,4 +87,46 @@ public void issue233ShouldNotRemoveWhitespaceFromLeader()
8487
verify(receiver).literal("leader", leaderValue);
8588
}
8689

90+
@Test
91+
public void shouldRecognizeRecordsWithNamespace()
92+
throws SAXException {
93+
final AttributesImpl attributes = new AttributesImpl();
94+
95+
marcXmlHandler.startElement(NAMESPACE, RECORD, "", attributes);
96+
marcXmlHandler.endElement(NAMESPACE, RECORD, "");
97+
98+
verify(receiver).startRecord("");
99+
verify(receiver).literal(TYPE, null);
100+
verify(receiver).endRecord();
101+
102+
verifyNoMoreInteractions(receiver);
103+
}
104+
105+
@Test
106+
public void shouldNotRecognizeRecordsWithoutNamespace()
107+
throws SAXException {
108+
final AttributesImpl attributes = new AttributesImpl();
109+
110+
marcXmlHandler.startElement(null, RECORD, "", attributes);
111+
marcXmlHandler.endElement(null, RECORD, "");
112+
113+
verifyNoMoreInteractions(receiver);
114+
}
115+
116+
@Test
117+
public void issue330ShouldOptionallyRecognizeRecordsWithoutNamespace()
118+
throws SAXException {
119+
final AttributesImpl attributes = new AttributesImpl();
120+
121+
marcXmlHandler.setNamespace(null);
122+
marcXmlHandler.startElement(null, RECORD, "", attributes);
123+
marcXmlHandler.endElement(null, RECORD, "");
124+
125+
verify(receiver).startRecord("");
126+
verify(receiver).literal(TYPE, null);
127+
verify(receiver).endRecord();
128+
129+
verifyNoMoreInteractions(receiver);
130+
}
131+
87132
}

metamorph-api/src/main/java/org/metafacture/metamorph/api/helpers/AbstractFlushingCollect.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,16 @@
2424
*/
2525
public abstract class AbstractFlushingCollect extends AbstractCollect {
2626

27+
private boolean flushIncomplete = true;
28+
29+
public final void setFlushIncomplete(final boolean flushIncomplete) {
30+
this.flushIncomplete = flushIncomplete;
31+
}
32+
2733
@Override
2834
public final void flush(final int recordCount, final int entityCount) {
2935
if (isSameRecord(recordCount) && sameEntityConstraintSatisfied(entityCount)) {
30-
if(isConditionMet()) {
36+
if(isConditionMet() && (flushIncomplete || isComplete())) {
3137
emit();
3238
}
3339
if (getReset()) {

metamorph/src/main/resources/schemata/metamorph.xsd

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,8 @@
283283
<attribute name="name" type="string" use="required" />
284284
<attribute name="value" type="string" use="required" />
285285

286+
<attribute name="flushIncomplete" type="boolean" use="optional"
287+
default="true" />
286288
<attribute name="reset" type="boolean" use="optional"
287289
default="false" />
288290
<attribute name="sameEntity" type="boolean" use="optional"
@@ -301,6 +303,8 @@
301303
<attribute name="name" type="string" use="required" />
302304
<attribute name="value" type="string" use="required" />
303305

306+
<attribute name="flushIncomplete" type="boolean" use="optional"
307+
default="true" />
304308
<attribute name="reset" type="boolean" use="optional"
305309
default="false" />
306310
<attribute name="sameEntity" type="boolean" use="optional"
@@ -442,6 +446,8 @@
442446
have an entity-name element otherwise an empty name is emitted</documentation>
443447
</annotation>
444448
</attribute>
449+
<attribute name="flushIncomplete" type="boolean" use="optional"
450+
default="true" />
445451
<attribute name="reset" type="boolean" use="optional"
446452
default="false" />
447453
<attribute name="sameEntity" type="boolean" use="optional"

metamorph/src/test/java/org/metafacture/metamorph/collectors/CombineTest.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.metafacture.metamorph.collectors;
1717

1818
import static org.mockito.Mockito.inOrder;
19+
import static org.mockito.Mockito.verifyNoMoreInteractions;
1920

2021
import org.junit.Rule;
2122
import org.junit.Test;
@@ -165,6 +166,38 @@ public void shouldEmitCurrentValueOnFlushEvent() {
165166
ordered.verifyNoMoreInteractions();
166167
}
167168

169+
@Test
170+
public void shouldNotEmitCurrentValueOnFlushEventIfIncomplete() {
171+
metamorph = InlineMorph.in(this)
172+
.with("<rules>")
173+
.with(" <combine name='combi' value='${one}${two}' flushWith='e' flushIncomplete='false' reset='true'>")
174+
.with(" <data source='e.l' name='one' />")
175+
.with(" <data source='e.m' name='two' />")
176+
.with(" </combine>")
177+
.with("</rules>")
178+
.createConnectedTo(receiver);
179+
180+
metamorph.startRecord("1");
181+
metamorph.startEntity("e");
182+
metamorph.literal("l", "1");
183+
metamorph.endEntity();
184+
metamorph.startEntity("e");
185+
metamorph.literal("l", "2");
186+
metamorph.literal("m", "2");
187+
metamorph.endEntity();
188+
metamorph.startEntity("e");
189+
metamorph.literal("l", "3");
190+
metamorph.endEntity();
191+
metamorph.endRecord();
192+
193+
final InOrder ordered = inOrder(receiver);
194+
ordered.verify(receiver).startRecord("1");
195+
ordered.verify(receiver).literal("combi", "22");
196+
ordered.verify(receiver).endRecord();
197+
ordered.verifyNoMoreInteractions();
198+
verifyNoMoreInteractions(receiver);
199+
}
200+
168201
@Test
169202
public void shouldPostprocessCombinedValue() {
170203
metamorph = InlineMorph.in(this)

metamorph/src/test/java/org/metafacture/metamorph/collectors/EntityTest.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import static org.mockito.Mockito.inOrder;
1919
import static org.mockito.Mockito.times;
20+
import static org.mockito.Mockito.verifyNoMoreInteractions;
2021

2122
import org.junit.Rule;
2223
import org.junit.Test;
@@ -119,6 +120,40 @@ public void shouldEmitEnityOnFlushEvent() {
119120
ordered.verifyNoMoreInteractions();
120121
}
121122

123+
@Test
124+
public void shouldNotEmitEnityOnFlushEventIfIncomplete() {
125+
metamorph = InlineMorph.in(this)
126+
.with("<rules>")
127+
.with(" <entity name='entity' flushWith='record' flushIncomplete='false'>")
128+
.with(" <data source='d1' name='l1' />")
129+
.with(" <data source='d2' name='l2' />")
130+
.with(" </entity>")
131+
.with("</rules>")
132+
.createConnectedTo(receiver);
133+
134+
metamorph.startRecord("1");
135+
metamorph.literal("d1", "a");
136+
metamorph.literal("d1", "b");
137+
metamorph.literal("d2", "c");
138+
metamorph.endRecord();
139+
metamorph.startRecord("2");
140+
metamorph.literal("d2", "c");
141+
metamorph.endRecord();
142+
143+
final InOrder ordered = inOrder(receiver);
144+
ordered.verify(receiver).startRecord("1");
145+
ordered.verify(receiver).startEntity("entity");
146+
ordered.verify(receiver).literal("l1", "a");
147+
ordered.verify(receiver).literal("l1", "b");
148+
ordered.verify(receiver).literal("l2", "c");
149+
ordered.verify(receiver).endEntity();
150+
ordered.verify(receiver).endRecord();
151+
ordered.verify(receiver).startRecord("2");
152+
ordered.verify(receiver).endRecord();
153+
ordered.verifyNoMoreInteractions();
154+
verifyNoMoreInteractions(receiver);
155+
}
156+
122157
@Test
123158
public void shouldEmitEntityOnEachFlushEvent() {
124159
metamorph = InlineMorph.in(this)
@@ -488,7 +523,7 @@ public void shouldEmitEntityContentsAgainIfResetIsFalse() {
488523
}
489524

490525
@Test
491-
public void shouldNotEmitEntityContentsAgainIfResetIsFalse() {
526+
public void shouldNotEmitEntityContentsAgainIfResetIsTrue() {
492527
metamorph = InlineMorph.in(this)
493528
.with("<rules>")
494529
.with(" <entity name='entity' reset='true'>")

metamorph/src/test/java/org/metafacture/metamorph/collectors/EqualsFilterTest.java

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static org.mockito.ArgumentMatchers.eq;
2020
import static org.mockito.Mockito.inOrder;
2121
import static org.mockito.Mockito.never;
22+
import static org.mockito.Mockito.verifyNoMoreInteractions;
2223

2324
import org.junit.Rule;
2425
import org.junit.Test;
@@ -233,4 +234,85 @@ public void shouldFireIfLiteralsInEntitiesAreReceivedThatAreNotListedInStatement
233234
ordered.verifyNoMoreInteractions();
234235
}
235236

237+
@Test
238+
public void shouldFireOnFlush() {
239+
metamorph = InlineMorph.in(this)
240+
.with("<rules>")
241+
.with(" <equalsFilter name='equalsFiltered' value='${one}' flushWith='field1.data2'>")
242+
.with(" <data source='field1.data1' name='one' />")
243+
.with(" <data source='field1.data2' name='two' />")
244+
.with(" </equalsFilter>")
245+
.with("</rules>")
246+
.createConnectedTo(receiver);
247+
248+
metamorph.startRecord("1");
249+
metamorph.startEntity("field1");
250+
metamorph.literal("data1", "a");
251+
metamorph.endEntity();
252+
metamorph.endRecord();
253+
metamorph.startRecord("2");
254+
metamorph.startEntity("field1");
255+
metamorph.literal("data2", "a");
256+
metamorph.endEntity();
257+
metamorph.endRecord();
258+
metamorph.startRecord("3");
259+
metamorph.startEntity("field1");
260+
metamorph.literal("data1", "a");
261+
metamorph.literal("data2", "a");
262+
metamorph.endEntity();
263+
metamorph.endRecord();
264+
265+
final InOrder ordered = inOrder(receiver);
266+
ordered.verify(receiver).startRecord("1");
267+
ordered.verify(receiver).endRecord();
268+
ordered.verify(receiver).startRecord("2");
269+
ordered.verify(receiver).literal("equalsFiltered", "");
270+
ordered.verify(receiver).endRecord();
271+
ordered.verify(receiver).startRecord("3");
272+
ordered.verify(receiver).literal("equalsFiltered", "a");
273+
ordered.verify(receiver).endRecord();
274+
ordered.verifyNoMoreInteractions();
275+
verifyNoMoreInteractions(receiver);
276+
}
277+
278+
@Test
279+
public void shouldNotFireOnFlushIfIncomplete() {
280+
metamorph = InlineMorph.in(this)
281+
.with("<rules>")
282+
.with(" <equalsFilter name='equalsFiltered' value='${one}' flushWith='field1.data2' flushIncomplete='false'>")
283+
.with(" <data source='field1.data1' name='one' />")
284+
.with(" <data source='field1.data2' name='two' />")
285+
.with(" </equalsFilter>")
286+
.with("</rules>")
287+
.createConnectedTo(receiver);
288+
289+
metamorph.startRecord("1");
290+
metamorph.startEntity("field1");
291+
metamorph.literal("data1", "a");
292+
metamorph.endEntity();
293+
metamorph.endRecord();
294+
metamorph.startRecord("2");
295+
metamorph.startEntity("field1");
296+
metamorph.literal("data2", "a");
297+
metamorph.endEntity();
298+
metamorph.endRecord();
299+
metamorph.startRecord("3");
300+
metamorph.startEntity("field1");
301+
metamorph.literal("data1", "a");
302+
metamorph.literal("data2", "a");
303+
metamorph.endEntity();
304+
metamorph.endRecord();
305+
306+
final InOrder ordered = inOrder(receiver);
307+
ordered.verify(receiver).startRecord("1");
308+
ordered.verify(receiver).endRecord();
309+
ordered.verify(receiver).startRecord("2");
310+
ordered.verify(receiver).endRecord();
311+
ordered.verify(receiver).startRecord("3");
312+
ordered.verify(receiver).literal("equalsFiltered", "a");
313+
ordered.verify(receiver).endRecord();
314+
ordered.verifyNoMoreInteractions();
315+
verifyNoMoreInteractions(receiver);
316+
}
317+
236318
}

0 commit comments

Comments
 (0)