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.

Reply via email to