/*
* 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 com.addthis.hydra.task.map;
import com.addthis.bundle.core.Bundle;
import com.addthis.bundle.core.Bundles;
import com.addthis.bundle.util.AutoField;
import com.addthis.bundle.value.ValueFactory;
import com.addthis.bundle.value.ValueMap;
import com.addthis.bundle.value.ValueMapEntry;
import com.addthis.bundle.value.ValueObject;
import com.addthis.hydra.data.filter.bundle.BundleFilter;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* This StreamBuilder splits a ValueMap amongst multiple bundles.
* Each bundle will have the same fields as the original with the exception
* of the field specified to use as the map, which won't be duplicated
* and will have one entry in each bundle with names as specified by keyField and valueField.
*/
public class StreamMapSplitBuilder extends StreamBuilder {
/** The map field to split into multiple bundles */
@JsonProperty(required = true) private AutoField field;
/** The field name in which to place each key in the new bundle */
@JsonProperty(required = true) private AutoField keyField;
/** The field name in which to place each value in the new bundle */
@JsonProperty(required = true) private AutoField valueField;
/** If true, a copy of the bundle without any key and value set will also be emitted
* (map field will also be excluded)
* The bundle will be emitted even if there is no map field in the bundle. */
@JsonProperty private boolean emitOriginal = false;
@JsonProperty private BundleFilter emitFilter;
@Override
public void init() {}
@Override
public void process(Bundle bundle, StreamEmitter emitter) {
ValueObject obj = field.getValue(bundle);
field.removeValue(bundle);
if ((obj != null) && (obj.getObjectType() == ValueObject.TYPE.MAP)) {
ValueMap map = obj.asMap();
for (ValueMapEntry entry : map) {
Bundle newBundle = Bundles.deepCopyBundle(bundle);
keyField.setValue(newBundle, ValueFactory.create(entry.getKey()));
valueField.setValue(newBundle, entry.getValue());
if (emitFilter == null || emitFilter.filter(newBundle)) {
emitter.emit(newBundle);
}
}
}
if (emitOriginal && (emitFilter == null || emitFilter.filter(bundle))) {
emitter.emit(bundle);
}
}
}