/* * 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.basis.util.LessStrings; import com.addthis.codec.annotations.FieldConfig; import com.addthis.hydra.data.tree.DataTreeNode; /** * This {@link PathElement PathElement} <span class="hydra-summary">creates sibling path elements in the tree</span>. * <p/> * <p>In general, when a sequence (ie. an array) of path elements is specified, * then successor path elements in the sequence are placed as child elements * of the preceding path elements. When using the "branch" path element and * the "list" parameter, the "list" parameter will accept an array of * path element arrays. This will generate N path element siblings in the tree, * where N is the number of path element arrays that are specified.</p> * <p/> * <p>When using the "branch" path element and the "each" parameter, * this is equivalent to using the "list" parameter where all the * path element arrays contain one element, and the number of * path element arrays is equal to the size of the "each" parameter.</p> * <p/> * @user-reference */ public final class PathBranch extends PathElement { /** * Sequence of path elements that will be placed as siblings in the tree. */ @FieldConfig(codable = true) private PathElement[] each; /** * Sequence of path element arrays that will be placed as siblings in the tree. */ @FieldConfig(codable = true) private ArrayList<PathElement[]> list; private int count; public PathBranch() { } public PathBranch(PathElement[] each) { this.each = each; } @Override public String toString() { return "[PathEach each=" + (each != null ? LessStrings.join(each, ",") : "null") + " list=" + list + "]"; } public void setEach(PathElement[] each) { if (count > 0) { throw new IllegalArgumentException("setEach only valid before resolving"); } this.each = each; } public void setList(ArrayList<PathElement[]> list) { if (count > 0) { throw new IllegalArgumentException("setEach only valid before resolving"); } this.list = list; } @Override public void resolve(TreeMapper mapper) { super.resolve(mapper); if (each != null) { for (PathElement pe : each) { pe.resolve(mapper); } count += each.length; } if (list != null) { for (PathElement[] pe : list) { for (PathElement p : pe) { p.resolve(mapper); } } count += list.size(); } } @Override public List<DataTreeNode> getNextNodeList(TreeMapState state) { List<DataTreeNode> res = new ArrayList<>(count); if (each != null) { for (PathElement anEach : each) { List<DataTreeNode> children = state.processPathElement(anEach); if (children != null) { res.addAll(children); } } } if (list != null) { for (PathElement[] pe : list) { List<DataTreeNode> children = state.processPath(pe); if (children != null) { res.addAll(children); } } } if (!res.isEmpty() || op) { return res; } else { return null; } } }