/* * 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.output.tree; import java.util.ArrayList; import java.util.List; import com.addthis.bundle.core.Bundle; import com.addthis.bundle.core.BundleField; import com.addthis.bundle.util.ValueUtil; import com.addthis.bundle.value.ValueObject; import com.addthis.bundle.value.ValueTranslationException; import com.addthis.codec.annotations.FieldConfig; import com.addthis.codec.json.CodecJSON; import com.addthis.hydra.data.query.BoundedValue; import com.addthis.hydra.data.query.QueryElementField; import com.addthis.hydra.data.tree.DataTreeNode; import com.addthis.hydra.data.tree.DataTreeNodeActor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class PathQueryElementField extends QueryElementField { private static final Logger log = LoggerFactory.getLogger(PathQueryElementField.class); @FieldConfig(codable = true) public ResolvableBoundedValue[] keys; public void resolve(TreeMapper mapper) { if (keys != null) { for (ResolvableBoundedValue key : keys) { key.resolve(mapper); } } } public List<ValueObject> getValues(DataTreeNode node, TreeMapState state) { if (keys == null) { return new ArrayList<>(); } ArrayList<ValueObject> ret = new ArrayList<>(keys.length); DataTreeNodeActor actor = node.getData(name); if (actor != null && keys != null) { for (int i = 0; i < keys.length; i++) { String name = keys[i].name; if (keys[i].key != null) { // TODO: filter? name = ValueUtil.asNativeString(keys[i].getKeyValue(state.getBundle())); } ValueObject qv = actor.onValueQuery(name); if (keys[i].bounded) { try { ret.add(keys[i].validate(qv.asLong().getLong()) ? qv : null); } catch (ValueTranslationException | NumberFormatException ex) { ret.add(null); } } else { ret.add(qv); } } return ret; } for (int i = 0; i < keys.length; i++) { ret.add(null); } return ret; } public static class ResolvableBoundedValue extends BoundedValue { @FieldConfig(codable = true) public String key; private BundleField bundleField; public void resolve(TreeMapper mapper) { bundleField = mapper.getFormat().getField(key); } /** */ public final ValueObject getKeyValue(Bundle p) { try { ValueObject pv = null; if (bundleField != null) { pv = p.getValue(bundleField); } return pv; } catch (NullPointerException ex) { try { log.warn("NPE: keyAccess=" + bundleField + " p=" + p + " in " + CodecJSON.encodeString( this)); } catch (Exception e) { e.printStackTrace(); } throw ex; } } } }