/*
* Copyright 2016 Deutsche Nationalbibliothek
*
* Licensed under the Apache License, Version 2.0 the "License";
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.culturegraph.mf.mangling;
import org.culturegraph.mf.framework.FluxCommand;
import org.culturegraph.mf.framework.StreamReceiver;
import org.culturegraph.mf.framework.annotations.Description;
import org.culturegraph.mf.framework.annotations.In;
import org.culturegraph.mf.framework.annotations.Out;
import org.culturegraph.mf.framework.helpers.DefaultStreamPipe;
/**
* Flattens all entities in a stream by prefixing the literals with the entity
* paths. The stream emitted by this module is guaranteed to not contain any
* <i>start-entity</i> and <i>end-entity</i> events.
* <p>
* For example, take the following sequence of events:
* <pre>{@literal
* start-record "1"
* literal "top-level": literal-value
* start-entity "entity"
* literal "nested": literal-value
* end-entity
* end-record
* }</pre>
*
* These events are transformed by the {@code StreamFlattener} into the
* following sequence of events:
* <pre>{@literal
* start-record "1"
* literal "top-level": literal-value
* literal "entity.nested": literal-value
* end-record
* }</pre>
*
* @author Christoph Böhme (rewrite)
* @author Markus Michael Geipel
* @see EntityPathTracker
*
*/
@Description("flattens out entities in a stream by introducing dots in literal names")
@In(StreamReceiver.class)
@Out(StreamReceiver.class)
@FluxCommand("flatten")
public final class StreamFlattener extends DefaultStreamPipe<StreamReceiver> {
public static final String DEFAULT_ENTITY_MARKER = ".";
private final EntityPathTracker pathTracker = new EntityPathTracker();
public StreamFlattener() {
setEntityMarker(DEFAULT_ENTITY_MARKER);
}
public String getEntityMarker() {
return pathTracker.getEntitySeparator();
}
public void setEntityMarker(final String entityMarker) {
pathTracker.setEntitySeparator(entityMarker);
}
@Override
public void startRecord(final String identifier) {
assert !isClosed();
pathTracker.startRecord(identifier);
getReceiver().startRecord(identifier);
}
@Override
public void endRecord() {
assert !isClosed();
pathTracker.endRecord();
getReceiver().endRecord();
}
@Override
public void startEntity(final String name) {
assert !isClosed();
pathTracker.startEntity(name);
}
@Override
public void endEntity() {
assert !isClosed();
pathTracker.endEntity();
}
@Override
public void literal(final String name, final String value) {
assert !isClosed();
getReceiver().literal(pathTracker.getCurrentPathWith(name), value);
}
public String getCurrentEntityName() {
return pathTracker.getCurrentEntityName();
}
public String getCurrentPath() {
return pathTracker.getCurrentPath();
}
}