This is an automated email from the ASF dual-hosted git repository. ahuber pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/isis.git
commit f485b1b06f0b99405b3712ea8bd5463d071e1e9f Author: Andi Huber <ahu...@apache.org> AuthorDate: Fri May 4 15:43:23 2018 +0200 ISIS-1943: extending the tree API: introduces TreePath Task-Url: https://issues.apache.org/jira/browse/ISIS-1943 --- .../org/apache/isis/applib/tree/LazyTreeNode.java | 35 +++++++++++++++ .../java/org/apache/isis/applib/tree/TreeNode.java | 4 ++ .../java/org/apache/isis/applib/tree/TreePath.java | 50 ++++++++++++++++++++++ .../apache/isis/applib/tree/TreePath_Default.java | 47 ++++++++++++++++++++ .../components/tree/IsisToWicketTreeAdapter.java | 3 +- 5 files changed, 138 insertions(+), 1 deletion(-) diff --git a/core/applib/src/main/java/org/apache/isis/applib/tree/LazyTreeNode.java b/core/applib/src/main/java/org/apache/isis/applib/tree/LazyTreeNode.java index 1d75d33..98ce49f 100644 --- a/core/applib/src/main/java/org/apache/isis/applib/tree/LazyTreeNode.java +++ b/core/applib/src/main/java/org/apache/isis/applib/tree/LazyTreeNode.java @@ -19,10 +19,12 @@ package org.apache.isis.applib.tree; import java.util.Objects; +import java.util.concurrent.atomic.LongAdder; import java.util.stream.Stream; import org.apache.isis.applib.annotation.Value; import org.apache.isis.applib.internal.base._Lazy; +import org.apache.isis.applib.internal.exceptions._Exceptions; @Value(semanticsProviderName="org.apache.isis.core.metamodel.facets.value.treenode.TreeNodeValueSemanticsProvider") public class LazyTreeNode<T> implements TreeNode<T> { @@ -30,6 +32,7 @@ public class LazyTreeNode<T> implements TreeNode<T> { private final T value; private final Class<? extends TreeAdapter<T>> treeAdapterClass; private final _Lazy<TreeAdapter<T>> treeAdapter = _Lazy.of(this::newTreeAdapter); + private final _Lazy<TreePath> treePath = _Lazy.of(this::resolveTreePath); public static <T> TreeNode<T> of(T value, Class<? extends TreeAdapter<T>> treeAdapterClass) { return new LazyTreeNode<T>(value, treeAdapterClass); @@ -73,6 +76,11 @@ public class LazyTreeNode<T> implements TreeNode<T> { return treeAdapterClass; } + @Override + public TreePath getPositionAsPath() { + return treePath.get(); + } + // -- HELPER private TreeAdapter<T> newTreeAdapter() { @@ -92,5 +100,32 @@ public class LazyTreeNode<T> implements TreeNode<T> { return of(value, getTreeAdapterClass()); } + private TreePath resolveTreePath() { + final TreeNode<T> parent = getParentIfAny(); + if(parent==null) { + return TreePath.root(); + } + return parent.getPositionAsPath().append(indexWithinSiblings(parent)); + } + + /* + * @return zero based index + */ + private int indexWithinSiblings(TreeNode<T> parent) { + final LongAdder indexOneBased = new LongAdder(); + + boolean found = parent.streamChildren() + .peek(__->indexOneBased.increment()) + .anyMatch(sibling->this.equals(sibling)) + ; + + if(!found) { + throw _Exceptions.unexpectedCodeReach(); + } + + return indexOneBased.intValue()-1; + } + + } diff --git a/core/applib/src/main/java/org/apache/isis/applib/tree/TreeNode.java b/core/applib/src/main/java/org/apache/isis/applib/tree/TreeNode.java index e387c0c..7ebb3ee 100644 --- a/core/applib/src/main/java/org/apache/isis/applib/tree/TreeNode.java +++ b/core/applib/src/main/java/org/apache/isis/applib/tree/TreeNode.java @@ -51,6 +51,10 @@ public interface TreeNode<T> { public default boolean isLeaf() { return getChildCount() == 0; } + + // -- PATH INFO + + public TreePath getPositionAsPath(); // -- CONSTRUCTION diff --git a/core/applib/src/main/java/org/apache/isis/applib/tree/TreePath.java b/core/applib/src/main/java/org/apache/isis/applib/tree/TreePath.java new file mode 100644 index 0000000..0e8c349 --- /dev/null +++ b/core/applib/src/main/java/org/apache/isis/applib/tree/TreePath.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.isis.applib.tree; + +import java.io.Serializable; + +/** + * Provides an unambiguous way to address nodes by position within a tree-structure. Examples: + * <ul> + * <li>/0 ... the tree root</li> + * <li>/0/1 ... the second child of root</li> + * <li>/0/0/0 ... the first child of first child of root</li> + * </ul> + * @since 2.0.0 + */ +public interface TreePath extends Serializable { + + /** + * @param indexWithinSiblings + * @return a new TreePath instance composed of this with one canonical path entry added + */ + public TreePath append(int indexWithinSiblings); + + // -- CONSTRUCTION + + public static TreePath of(final int ... canonicalPath) { + return new TreePath_Default(canonicalPath); + } + + public static TreePath root() { + return of(0); + } + +} diff --git a/core/applib/src/main/java/org/apache/isis/applib/tree/TreePath_Default.java b/core/applib/src/main/java/org/apache/isis/applib/tree/TreePath_Default.java new file mode 100644 index 0000000..ce30341 --- /dev/null +++ b/core/applib/src/main/java/org/apache/isis/applib/tree/TreePath_Default.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.isis.applib.tree; + +import java.util.Objects; + +/** + * Package private mixin for TreePath. + */ +class TreePath_Default implements TreePath { + + private static final long serialVersionUID = 530511373409525896L; + private final int[] canonicalPath; + + TreePath_Default(int[] canonicalPath) { + Objects.requireNonNull(canonicalPath, "canonicalPath is required"); + if(canonicalPath.length<1) { + throw new IllegalArgumentException("canonicalPath must not be empty"); + } + this.canonicalPath = canonicalPath; + } + + @Override + public TreePath append(int indexWithinSiblings) { + int[] newCanonicalPath = new int[canonicalPath.length+1]; + System.arraycopy(canonicalPath, 0, newCanonicalPath, 0, canonicalPath.length); + newCanonicalPath[canonicalPath.length] = indexWithinSiblings; + return new TreePath_Default(newCanonicalPath); + } + +} diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/tree/IsisToWicketTreeAdapter.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/tree/IsisToWicketTreeAdapter.java index 766fd68..102a12a 100644 --- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/tree/IsisToWicketTreeAdapter.java +++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/tree/IsisToWicketTreeAdapter.java @@ -275,7 +275,8 @@ class IsisToWicketTreeAdapter { } /* - * Important! Models must be identifiable by their contained object. + * Important! Models must be identifiable by their contained object. Also IDs must be + * unique within a tree structure. */ @Override public boolean equals(Object obj) { -- To stop receiving notification emails like this one, please contact ahu...@apache.org.