/* * Copyright 2013, 2014 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.javaintegration; import java.util.Map; import org.culturegraph.mf.framework.FluxCommand; import org.culturegraph.mf.framework.StandardEventNames; import org.culturegraph.mf.framework.StreamReceiver; import org.culturegraph.mf.framework.annotations.In; import org.culturegraph.mf.framework.annotations.Out; import org.culturegraph.mf.framework.helpers.DefaultObjectPipe; /** * Emits a {@link Map} as a record with a literal for each entry in the map. * When receiving an empty map only a <i>start-record</i> and <i>end-record</i> * event is emitted. * <p> * If the map contains an entry whose key value matches the one set as * {@link #setIdKey(Object)}, this entry's value is used as the record id. * <p> * The keys and values in the map can be of any type. They will be converted to * strings using their {@link Object#toString()} method. Neither key nor value * may be null. * <p> * The order in which the literals are emitted is unspecified. * <p> * For example, when receiving the following map with string keys and integer * values: * <pre>{@literal * final Map<String, Integer> map = new HashMap<>(); * map.put("_id", 1); * map.put("lit-A", 2); * map.put("lit-B", 3); * }</pre> * Then this module will emit the following sequence of events: * <pre>{@literal * start-record "1" * literal "lit-A": 2 * literal "lit-B": 3 * end-record * }</pre> * * @author Christoph Böhme */ @In(Map.class) @Out(StreamReceiver.class) @FluxCommand("map-to-stream") public final class MapToStream extends DefaultObjectPipe<Map<?, ?>, StreamReceiver> { private Object idKey = StandardEventNames.ID; /** * Sets the key of the map entry that is used for the record id. * <p> * The default id key is "{@value StandardEventNames#ID}". * <p> * This parameter can be changed anytime during processing. The new value * becomes effective with the next record being processed. * * @param idKey the id key. The object passed here is used in a call to * {@link Map#get(Object)} to get the identifier value. */ public void setIdKey(final Object idKey) { this.idKey = idKey; } public Object getIdKey() { return idKey; } @Override public void process(final Map<?, ?> map) { final Object id = map.get(idKey); if (id == null) { getReceiver().startRecord(""); } else { getReceiver().startRecord(id.toString()); } for (final Map.Entry<?, ?> entry: map.entrySet()) { getReceiver().literal(entry.getKey().toString(), entry.getValue().toString()); } getReceiver().endRecord(); } }