Updated Branches:
  refs/heads/master a742f389c -> 7533ebd8a

ISIS-403: bookmarks now organize themselves into hierarchy

as per @Bookmarkable(AS_ROOT) or @Bookmarkable(AS_CHILD).


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/7533ebd8
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/7533ebd8
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/7533ebd8

Branch: refs/heads/master
Commit: 7533ebd8a55e02427f56d20ae9b8d653b9edfb9c
Parents: a742f38
Author: Dan Haywood <[email protected]>
Authored: Fri May 10 17:07:35 2013 +0200
Committer: Dan Haywood <[email protected]>
Committed: Fri May 10 17:07:35 2013 +0200

----------------------------------------------------------------------
 .../viewer/wicket/model/models/ActionModel.java    |   11 +-
 .../wicket/model/models/BookmarkTreeNode.java      |  135 ++++++++++++++-
 .../model/models/BookmarkTreeNodeComparator.java   |   61 +++++++
 .../wicket/model/models/BookmarkableModel.java     |   27 +++-
 .../wicket/model/models/BookmarkedPagesModel.java  |  136 ++++-----------
 .../viewer/wicket/model/models/EntityModel.java    |   21 ++-
 .../bookmarkedpages/BookmarkedPagesPanel.css       |   24 +++-
 .../bookmarkedpages/BookmarkedPagesPanel.html      |    2 +-
 .../bookmarkedpages/BookmarkedPagesPanel.java      |   34 +----
 .../ui/components/bookmarkedpages/slide-panel.js   |    7 +-
 .../isis/applib/annotation/BookmarkPolicy.java     |    2 +-
 .../isis/applib/annotation/Bookmarkable.java       |    2 +-
 .../spec/feature/ObjectAssociationFilters.java     |   12 ++
 13 files changed, 317 insertions(+), 157 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/7533ebd8/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionModel.java
----------------------------------------------------------------------
diff --git 
a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionModel.java
 
b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionModel.java
index 5f5cffc..1492fee 100644
--- 
a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionModel.java
+++ 
b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionModel.java
@@ -216,7 +216,7 @@ public class ActionModel extends 
BookmarkableModel<ObjectAdapter> {
             buf.append(abbreviated(titleOf(argumentAdapter), 8));
         }
 
-        final String actionTitle = adapter.titleString() + "." + 
objectAction.getName() + (buf.length()>0?"(" + buf.toString() + ")":"");
+        final String actionTitle = adapter.titleString(null) + "." + 
objectAction.getName() + (buf.length()>0?"(" + buf.toString() + ")":"");
         PageParameterNames.PAGE_TITLE.addStringTo(pageParameters, actionTitle);
 
         return pageParameters;
@@ -224,17 +224,22 @@ public class ActionModel extends 
BookmarkableModel<ObjectAdapter> {
 
 
     @Override
-    public boolean hasRootPolicy() {
+    public boolean hasAsRootPolicy() {
         return true;
     }
 
+    @Override
+    public boolean hasAsChildPolicy() {
+        return false;
+    }
+    
     //////////////////////////////////////////////////
     // helpers
     //////////////////////////////////////////////////
 
     
     private static String titleOf(ObjectAdapter argumentAdapter) {
-        return argumentAdapter!=null?argumentAdapter.titleString():"";
+        return argumentAdapter!=null?argumentAdapter.titleString(null):"";
     }
     
     private static String abbreviated(final String str, final int maxLength) {

http://git-wip-us.apache.org/repos/asf/isis/blob/7533ebd8/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BookmarkTreeNode.java
----------------------------------------------------------------------
diff --git 
a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BookmarkTreeNode.java
 
b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BookmarkTreeNode.java
index 16982cd..1c1d606 100644
--- 
a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BookmarkTreeNode.java
+++ 
b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BookmarkTreeNode.java
@@ -4,10 +4,18 @@ import java.io.Serializable;
 import java.util.List;
 
 import com.google.common.base.Function;
+import com.google.common.base.Objects;
 import com.google.common.collect.Lists;
 
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.oid.Oid;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociationFilters;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.wicket.model.mementos.PageParameterNames;
+
 public class BookmarkTreeNode implements Serializable {
     
         private static final long serialVersionUID = 1L;
@@ -18,21 +26,132 @@ public class BookmarkTreeNode implements Serializable {
             }
         };
         final PageParameters pageParameters;
-        private final List<PageParameters> children = Lists.newArrayList();
+        private final List<BookmarkTreeNode> children = Lists.newArrayList();
+
+        private final int depth;
         
-        public BookmarkTreeNode(BookmarkableModel<?> node) {
-            this.pageParameters = node.asPageParameters();
+        public static BookmarkTreeNode newRoot(BookmarkableModel<?> 
bookmarkableModel) {
+            return new BookmarkTreeNode(bookmarkableModel, 0);
+        }
+
+        private BookmarkTreeNode(BookmarkableModel<?> node, int depth) {
+            this.depth = depth;
+            this.pageParameters = node.getPageParameters();
         }
         public PageParameters getPageParameters() {
             return pageParameters;
         }
-        public List<PageParameters> getChildren() {
+        public List<BookmarkTreeNode> getChildren() {
             return children;
         }
         public BookmarkTreeNode addChild(BookmarkableModel<?> childModel) {
-            return null;
+            final BookmarkTreeNode childNode = new 
BookmarkTreeNode(childModel, depth+1);
+            children.add(childNode);
+            return childNode;
+        }
+        
+        /**
+         * Whether or not the provided {@link BookmarkableModel} matches that 
contained
+         * within this node, or any of its children.
+         * 
+         * <p>
+         * If it does, then the matched node's title is updated to that of the 
provided
+         * {@link BookmarkableModel}.
+         * 
+         * <p>
+         * The {@link PageParameters} (used for matching) is 
+         * {@link BookmarkableModel#getPageParameters() obtained} from the 
{@link BookmarkableModel}.
+         * 
+         * <p>
+         * The convoluted logic in this method is because we temporarily 
remove the title 
+         * in order to do the check.
+         * 
+         * @return - whether the provided candidate is found or was added to 
this node's tree.
+         */
+        public boolean matchAndUpdateTitle(BookmarkableModel<?> 
candidateBookmarkableModel) {
+
+            boolean inGraph = false;
+
+            // attempt to match this node.
+            final PageParameters candidatePP = 
candidateBookmarkableModel.getPageParameters();
+            inGraph = matchAndUpdateTitle(candidatePP, this.pageParameters);
+
+            // and also match recursively down to all children and 
grandchildren.
+            if(candidateBookmarkableModel.hasAsChildPolicy()) {
+                for(BookmarkTreeNode childNode: this.getChildren()) {
+                    inGraph = 
childNode.matchAndUpdateTitle(candidateBookmarkableModel) || inGraph; // 
evaluate each
+                }
+                
+                if(!inGraph) {
+                    inGraph = addToGraphIfParented(candidateBookmarkableModel);
+                }
+            }
+            return inGraph;
+        }
+
+        private boolean addToGraphIfParented(BookmarkableModel<?> 
candidateBookmarkableModel) {
+            
+            boolean whetherAdded = false;
+            // TODO: this ought to be move into a responsibility of 
BookmarkableModel, perhaps, rather than downcasting
+            if(candidateBookmarkableModel instanceof EntityModel) {
+                EntityModel entityModel = (EntityModel) 
candidateBookmarkableModel;
+                final ObjectAdapter candidateAdapter = entityModel.getObject();
+                final List<ObjectAssociation> properties = 
candidateAdapter.getSpecification().getAssociations(ObjectAssociationFilters.REFERENCE_PROPERTIES);
+                for (ObjectAssociation objectAssoc : properties) {
+                    final ObjectAdapter possibleParentAdapter = 
objectAssoc.get(candidateAdapter);
+                    if(possibleParentAdapter == null) {
+                        continue;
+                    } 
+                    final Oid possibleParentOid = 
possibleParentAdapter.getOid();
+                    if(possibleParentOid == null) {
+                        continue;
+                    } 
+                    final String possibleParentOidStr = 
possibleParentOid.enStringNoVersion(IsisContext.getOidMarshaller());
+                    final String thisOidStr = 
PageParameterNames.OBJECT_OID.getStringFrom(this.pageParameters);
+                    if(Objects.equal(thisOidStr, possibleParentOidStr)) {
+                        this.addChild(candidateBookmarkableModel);
+                        whetherAdded = true;
+                    }
+                }
+            }
+            return whetherAdded;
+        }
+
+        protected boolean matchAndUpdateTitle(final PageParameters 
candidatePP, PageParameters pageParameters) {
+
+            final String candidateTitle = 
PageParameterNames.PAGE_TITLE.getStringFrom(candidatePP);
+            String pageTitle = 
PageParameterNames.PAGE_TITLE.getStringFrom(pageParameters);
+
+            final String pageTitleKey = 
PageParameterNames.PAGE_TITLE.toString();
+            try {
+                // temporarily remove to do comparison
+                candidatePP.remove(pageTitleKey);
+
+                pageParameters.remove(pageTitleKey);
+                if(pageParameters.equals(candidatePP)) {
+                    // update the existing
+                    pageTitle = candidateTitle;
+                    return true;
+                }
+
+            } finally {
+                // restore
+                PageParameterNames.PAGE_TITLE.addStringTo(pageParameters, 
pageTitle);
+                PageParameterNames.PAGE_TITLE.addStringTo(candidatePP, 
candidateTitle);
+            }
+
+            // did not match, title not updated.
+            return false;
+        }
+
+        public void appendGraphTo(List<BookmarkTreeNode> list) {
+            list.add(this);
+            for (BookmarkTreeNode childNode : children) {
+                childNode.appendGraphTo(list);
+            }
+        }
+
+        public int getDepth() {
+            return depth;
         }
-//        public TreeNode exists(BookmarkableModel<?> candidateModel) {
-//            
-//        }
     }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/7533ebd8/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BookmarkTreeNodeComparator.java
----------------------------------------------------------------------
diff --git 
a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BookmarkTreeNodeComparator.java
 
b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BookmarkTreeNodeComparator.java
new file mode 100644
index 0000000..1759a08
--- /dev/null
+++ 
b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BookmarkTreeNodeComparator.java
@@ -0,0 +1,61 @@
+package org.apache.isis.viewer.wicket.model.models;
+
+import java.util.Comparator;
+
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+
+import org.apache.isis.core.metamodel.adapter.oid.OidMarshaller;
+import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.spec.ObjectSpecId;
+import org.apache.isis.core.metamodel.spec.SpecificationLoader;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.wicket.model.mementos.PageParameterNames;
+
+final class BookmarkTreeNodeComparator implements Comparator<BookmarkTreeNode> 
{
+    
+    @Override
+    public int compare(BookmarkTreeNode o1, BookmarkTreeNode o2) {
+        PageType pageType1 = 
PageParameterNames.PAGE_TYPE.getEnumFrom(o1.pageParameters, PageType.class);
+        PageType pageType2 = 
PageParameterNames.PAGE_TYPE.getEnumFrom(o2.pageParameters, PageType.class);
+        
+        final int pageTypeComparison = pageType1.compareTo(pageType2);
+        if(pageTypeComparison != 0) {
+            return pageTypeComparison;
+        }
+        
+        if(pageType1 == PageType.ENTITY) {
+            // sort by entity type
+            final String className1 = classNameOf(o1.pageParameters);
+            final String className2 = classNameOf(o2.pageParameters);
+            
+            final int classNameComparison = className1.compareTo(className2);
+            if(classNameComparison != 0) {
+                return classNameComparison;
+            }
+        }
+        String title1 = 
PageParameterNames.PAGE_TITLE.getStringFrom(o1.pageParameters);
+        String title2 = 
PageParameterNames.PAGE_TITLE.getStringFrom(o2.pageParameters);
+        return title1.compareTo(title2);
+    }
+
+    private String classNameOf(PageParameters pp) {
+        String oidStr = PageParameterNames.OBJECT_OID.getStringFrom(pp);
+        RootOid oid = getOidMarshaller().unmarshal(oidStr, RootOid.class);
+        ObjectSpecId objectSpecId = oid.getObjectSpecId();
+        final String className = 
getSpecificationLoader().lookupBySpecId(objectSpecId).getIdentifier().getClassName();
+        return className;
+    }
+    
+    //////////////////////////////////////////////////
+    // Dependencies (from context)
+    //////////////////////////////////////////////////
+    
+    protected OidMarshaller getOidMarshaller() {
+        return IsisContext.getOidMarshaller();
+    }
+    
+    protected SpecificationLoader getSpecificationLoader() {
+        return IsisContext.getSpecificationLoader();
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/7533ebd8/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BookmarkableModel.java
----------------------------------------------------------------------
diff --git 
a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BookmarkableModel.java
 
b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BookmarkableModel.java
index 72c5913..b03ea78 100644
--- 
a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BookmarkableModel.java
+++ 
b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BookmarkableModel.java
@@ -21,6 +21,8 @@ package org.apache.isis.viewer.wicket.model.models;
 
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+
 public abstract class BookmarkableModel<T> extends ModelAbstract<T>  {
 
     private static final long serialVersionUID = 1L;
@@ -33,11 +35,32 @@ public abstract class BookmarkableModel<T> extends 
ModelAbstract<T>  {
         super(t);
     }
 
+    
+    private PageParameters cachedPageParameters;
+    
     /**
      * So can be bookmarked / added to <tt>BookmarkedPagesModel</tt>.
+     * 
+     * <p>
+     * Delegates to {@link #asPageParameters()}, and caches for performance.
+     */
+    public PageParameters getPageParameters() {
+        if(cachedPageParameters == null) {
+            cachedPageParameters = asPageParameters();
+        }
+        return cachedPageParameters;
+    }
+    
+    /**
+     * Generally, should use {@link #getPageParameters()}, since this is cached
+     * and {@link PageParameters} could be a bit expensive to compute
+     * (since they include the object's 
+     * {@link ObjectAdapter#titleString(ObjectAdapter) title}).
      */
-    public abstract PageParameters asPageParameters();
+    protected abstract PageParameters asPageParameters();
 
-    public abstract boolean hasRootPolicy();
+    public abstract boolean hasAsRootPolicy();
+    
+    public abstract boolean hasAsChildPolicy();
     
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/7533ebd8/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BookmarkedPagesModel.java
----------------------------------------------------------------------
diff --git 
a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BookmarkedPagesModel.java
 
b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BookmarkedPagesModel.java
index be2b64f..5c3192e 100644
--- 
a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BookmarkedPagesModel.java
+++ 
b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BookmarkedPagesModel.java
@@ -20,7 +20,6 @@
 package org.apache.isis.viewer.wicket.model.models;
 
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
 
@@ -30,18 +29,14 @@ import com.google.common.collect.Lists;
 
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 
-import org.apache.isis.applib.annotation.BookmarkPolicy;
-import org.apache.isis.core.metamodel.adapter.oid.OidMarshaller;
 import org.apache.isis.core.metamodel.adapter.oid.RootOid;
-import 
org.apache.isis.core.metamodel.facets.object.bookmarkable.BookmarkPolicyFacet;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.metamodel.spec.SpecificationLoader;
 import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.viewer.wicket.model.mementos.PageParameterNames;
 
 
-public class BookmarkedPagesModel extends ModelAbstract<List<? extends 
BookmarkTreeNode>> implements Iterable<PageParameters>{
+public class BookmarkedPagesModel extends ModelAbstract<List<? extends 
BookmarkTreeNode>> {
+
+    private static final BookmarkTreeNodeComparator COMPARATOR = new 
BookmarkTreeNodeComparator();
 
     private static final long serialVersionUID = 1L;
     
@@ -49,103 +44,59 @@ public class BookmarkedPagesModel extends 
ModelAbstract<List<? extends BookmarkT
     private transient PageParameters current;
     
     public void bookmarkPage(final BookmarkableModel<?> bookmarkableModel) {
-        if(bookmarkableModel.hasRootPolicy()) {
-            bookmarkRoot(bookmarkableModel);
+
+        final PageParameters candidatePP = 
bookmarkableModel.getPageParameters();
+        if(!isValidParameters(candidatePP)) {
+            return;
+        }
+
+        boolean foundInGraph = false;
+        for (BookmarkTreeNode eachNode : rootNodes) {
+            if(eachNode.matchAndUpdateTitle(bookmarkableModel)) {
+                current = candidatePP;
+                foundInGraph = true;
+            }
+        }
+
+        if(!foundInGraph && bookmarkableModel.hasAsRootPolicy()) {
+            rootNodes.add(BookmarkTreeNode.newRoot(bookmarkableModel));
+            Collections.sort(rootNodes, COMPARATOR);
+            current = candidatePP;
         }
+
+        return;
     }
 
-    protected void bookmarkRoot(final BookmarkableModel<?> bookmarkableModel) {
-        final PageParameters candidatePP = 
bookmarkableModel.asPageParameters();
-        
+
+    /**
+     * @return whether the {@link PageParameters} contain all required fields.
+     */
+    private static boolean isValidParameters(final PageParameters candidatePP) 
{
+
         // ignore if doesn't provide a page type for subsequent disambiguation
         PageType pageType = 
PageParameterNames.PAGE_TYPE.getEnumFrom(candidatePP, PageType.class);
         if(pageType==null) {
-            return;
+            return false;
         }
         
         // ignore if doesn't provide a title for rendering
         String candidateTitle = 
PageParameterNames.PAGE_TITLE.getStringFrom(candidatePP);
         if(candidateTitle==null) {
-            return;
+            return false;
         }
         
-        // look to see if exists already; if found then update title if need 
be.
-        // the convoluted logic here is because we temporarily remove the title
-        // in order to do the check.
-        final String pageTitleKey = PageParameterNames.PAGE_TITLE.toString();
-        try {
-            // temporarily remove to do comparison
-            candidatePP.remove(pageTitleKey);
-            
-            for (BookmarkTreeNode eachNode : rootNodes) {
-                PageParameters eachPP = eachNode.pageParameters;
-                String pageTitle = 
PageParameterNames.PAGE_TITLE.getStringFrom(eachPP);
-                try {
-                    eachPP.remove(pageTitleKey);
-                    if(eachPP.equals(candidatePP)) {
-                       pageTitle = candidateTitle; // update the existing
-                       current = eachPP;
-                       return;
-                    }
-                } finally {
-                    eachPP.add(PageParameterNames.PAGE_TITLE.toString(), 
pageTitle);
-                }
-            }
-        } finally {
-            PageParameterNames.PAGE_TITLE.addStringTo(candidatePP, 
candidateTitle);
-        }
-        
-        // if get here, then didn't find.
-        rootNodes.add(new BookmarkTreeNode(bookmarkableModel));
-        Collections.sort(rootNodes, new Comparator<BookmarkTreeNode>() {
-
-            @Override
-            public int compare(BookmarkTreeNode o1, BookmarkTreeNode o2) {
-                PageType pageType1 = 
PageParameterNames.PAGE_TYPE.getEnumFrom(o1.pageParameters, PageType.class);
-                PageType pageType2 = 
PageParameterNames.PAGE_TYPE.getEnumFrom(o2.pageParameters, PageType.class);
-                
-                final int pageTypeComparison = pageType1.compareTo(pageType2);
-                if(pageTypeComparison != 0) {
-                    return pageTypeComparison;
-                }
-                
-                if(pageType1 == PageType.ENTITY) {
-                    // sort by entity type
-                    final String className1 = classNameOf(o1.pageParameters);
-                    final String className2 = classNameOf(o2.pageParameters);
-                    
-                    final int classNameComparison = 
className1.compareTo(className2);
-                    if(classNameComparison != 0) {
-                        return classNameComparison;
-                    }
-                }
-                String title1 = 
PageParameterNames.PAGE_TITLE.getStringFrom(o1.pageParameters);
-                String title2 = 
PageParameterNames.PAGE_TITLE.getStringFrom(o2.pageParameters);
-                return title1.compareTo(title2);
-            }
-
-            private String classNameOf(PageParameters o1) {
-                String oidStr1 = 
PageParameterNames.OBJECT_OID.getStringFrom(o1);
-                RootOid oid1 = getOidMarshaller().unmarshal(oidStr1, 
RootOid.class);
-                ObjectSpecId objectSpecId1 = oid1.getObjectSpecId();
-                final String className1 = 
getSpecificationLoader().lookupBySpecId(objectSpecId1).getIdentifier().getClassName();
-                return className1;
-            }
-        });
-        current = candidatePP;
+        return true;
     }
 
-    
     @Override
     protected List<BookmarkTreeNode> load() {
-        return rootNodes;
+        List<BookmarkTreeNode> depthFirstGraph = Lists.newArrayList();
+        for (BookmarkTreeNode rootNode : rootNodes) {
+            rootNode.appendGraphTo(depthFirstGraph);
+        }
+        return depthFirstGraph;
     }
 
-    @Override
-    public Iterator<PageParameters> iterator() {
-        return 
Iterators.unmodifiableIterator(Iterators.transform(rootNodes.iterator(), 
BookmarkTreeNode.AS_PAGE_PARAMETERS));
-    }
-    
     public boolean isCurrent(PageParameters pageParameters) {
         return Objects.equal(current, pageParameters);
     }
@@ -170,18 +121,5 @@ public class BookmarkedPagesModel extends 
ModelAbstract<List<? extends BookmarkT
         return rootNodes.isEmpty();
     }
 
-    
-
-    //////////////////////////////////////////////////
-    // Dependencies (from context)
-    //////////////////////////////////////////////////
-    
-    protected OidMarshaller getOidMarshaller() {
-        return IsisContext.getOidMarshaller();
-    }
-    
-    protected SpecificationLoader getSpecificationLoader() {
-        return IsisContext.getSpecificationLoader();
-    }
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/7533ebd8/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
----------------------------------------------------------------------
diff --git 
a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
 
b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
index d417b58..2942e94 100644
--- 
a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
+++ 
b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
@@ -82,7 +82,7 @@ public class EntityModel extends 
BookmarkableModel<ObjectAdapter> {
         }
         
         PageParameterNames.PAGE_TYPE.addEnumTo(pageParameters, 
PageType.ENTITY);
-        PageParameterNames.PAGE_TITLE.addStringTo(pageParameters, 
adapter.titleString());
+        PageParameterNames.PAGE_TITLE.addStringTo(pageParameters, 
adapter.titleString(null));
 
         return pageParameters;
     }
@@ -139,7 +139,6 @@ public class EntityModel extends 
BookmarkableModel<ObjectAdapter> {
      * {@link ConcurrencyException}, if any, that might have occurred 
previously
      */
     private ConcurrencyException concurrencyException;
-    private ConcurrencyChecking loadingHint;
 
     // //////////////////////////////////////////////////////////
     // constructors
@@ -182,11 +181,23 @@ public class EntityModel extends 
BookmarkableModel<ObjectAdapter> {
     }
 
 
-    public boolean hasRootPolicy() {
+    public boolean hasAsRootPolicy() {
+        return hasBookmarkPolicy(BookmarkPolicy.AS_ROOT);
+    }
+
+    public boolean hasAsChildPolicy() {
+        return hasBookmarkPolicy(BookmarkPolicy.AS_CHILD);
+    }
+
+    private boolean hasBookmarkPolicy(final BookmarkPolicy policy) {
+        final BookmarkPolicyFacet facet = getBookmarkPolicyFacetIfAny();
+        return facet != null && facet.value() == policy;
+    }
+    
+    private BookmarkPolicyFacet getBookmarkPolicyFacetIfAny() {
         final ObjectSpecId specId = 
getObjectAdapterMemento().getObjectSpecId();
         final ObjectSpecification objectSpec = 
getSpecificationLoader().lookupBySpecId(specId);
-        final BookmarkPolicyFacet facet = 
objectSpec.getFacet(BookmarkPolicyFacet.class);
-        return facet != null && facet.value() == BookmarkPolicy.ROOT;
+        return objectSpec.getFacet(BookmarkPolicyFacet.class);
     }
 
 

http://git-wip-us.apache.org/repos/asf/isis/blob/7533ebd8/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/BookmarkedPagesPanel.css
----------------------------------------------------------------------
diff --git 
a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/BookmarkedPagesPanel.css
 
b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/BookmarkedPagesPanel.css
index f94d1de..1ced8c1 100644
--- 
a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/BookmarkedPagesPanel.css
+++ 
b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/BookmarkedPagesPanel.css
@@ -112,7 +112,7 @@
     font-weight:bold;
 }
 
-#panel {
+#bookmarkedPagesSlidingDiv {
     border-radius: 0px 8px 8px 0px;
     position:fixed;
     left:0px;
@@ -122,9 +122,29 @@
     width:0;/*new line*/
     z-index: 1;
 }
-#panel .content {
+#bookmarkedPagesSlidingDiv .content {
     width:290px;
     margin-left:30px;
     
     display: none;
 }
+
+
+.bookmarkDepth0 {
+    padding-left: 0px; 
+}
+.bookmarkDepth1 {
+    padding-left: 20px;  
+}
+.bookmarkDepth2 {
+    padding-left: 40px;  
+}
+.bookmarkDepth3 {
+    padding-left: 60px;  
+}
+.bookmarkDepth4 {
+    padding-left: 80px;  
+}
+.bookmarkDepth5 {
+    padding-left: 100px;  
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/7533ebd8/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/BookmarkedPagesPanel.html
----------------------------------------------------------------------
diff --git 
a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/BookmarkedPagesPanel.html
 
b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/BookmarkedPagesPanel.html
index 221c4ea..98347c2 100644
--- 
a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/BookmarkedPagesPanel.html
+++ 
b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/BookmarkedPagesPanel.html
@@ -26,7 +26,7 @@
                <wicket:panel>
             <div class="showPanelTab">
             </div>
-            <div id="panel"> <!--the hidden panel -->
+            <div id="bookmarkedPagesSlidingDiv">
                 <div class="content">
                     <div id="bookmarkedPages" class="bookmarkedPagesPanel 
bookmarkedPagesComponentType">
                         <a href="#" wicket:id="clearBookmarks" 
class="clearBookmarks" title="Clear Bookmarks">clear</a>

http://git-wip-us.apache.org/repos/asf/isis/blob/7533ebd8/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/BookmarkedPagesPanel.java
----------------------------------------------------------------------
diff --git 
a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/BookmarkedPagesPanel.java
 
b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/BookmarkedPagesPanel.java
index c998bba..63ab4fb 100644
--- 
a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/BookmarkedPagesPanel.java
+++ 
b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/BookmarkedPagesPanel.java
@@ -19,11 +19,7 @@
 
 package org.apache.isis.viewer.wicket.ui.components.bookmarkedpages;
 
-import java.util.List;
-
 import com.google.inject.Inject;
-import com.googlecode.wicket.jquery.core.Options;
-import com.googlecode.wicket.jquery.ui.interaction.resizable.ResizableBehavior;
 
 import org.apache.wicket.Page;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -36,7 +32,6 @@ import org.apache.wicket.markup.html.image.Image;
 import org.apache.wicket.markup.html.link.AbstractLink;
 import org.apache.wicket.markup.html.list.ListItem;
 import org.apache.wicket.markup.html.list.ListView;
-import org.apache.wicket.model.IModel;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.request.resource.JavaScriptResourceReference;
 import org.apache.wicket.request.resource.ResourceReference;
@@ -47,10 +42,10 @@ import 
org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpi;
 import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.viewer.wicket.model.mementos.PageParameterNames;
+import org.apache.isis.viewer.wicket.model.models.BookmarkTreeNode;
 import org.apache.isis.viewer.wicket.model.models.BookmarkedPagesModel;
 import org.apache.isis.viewer.wicket.model.models.ImageResourceCache;
 import org.apache.isis.viewer.wicket.model.models.PageType;
-import org.apache.isis.viewer.wicket.model.models.BookmarkTreeNode;
 import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistry;
 import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
 import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
@@ -77,32 +72,6 @@ public class BookmarkedPagesPanel extends 
PanelAbstract<BookmarkedPagesModel> {
     public BookmarkedPagesPanel(final String id, final BookmarkedPagesModel 
bookmarkedPagesModel) {
         super(id, bookmarkedPagesModel);
         buildGui();
-        
-//        Options options = new Options();
-//        
-//        add(new ResizableBehavior("#panel") {
-//            private static final long serialVersionUID = 1L;
-//
-//            @Override
-//            public void onResizeStop(AjaxRequestTarget target, int top, int 
left, int width, int height) {
-//                return;
-//            }
-//            
-//            @Override
-//            public void onResizeStart(AjaxRequestTarget target, int top, int 
left, int width, int height) {
-//                return;
-//            }
-//            
-//            @Override
-//            public boolean isResizeStopEventEnabled() {
-//                return false;
-//            }
-//            
-//            @Override
-//            public boolean isResizeStartEventEnabled() {
-//                return false;
-//            }
-//        });
     }
 
     private void buildGui() {
@@ -157,6 +126,7 @@ public class BookmarkedPagesPanel extends 
PanelAbstract<BookmarkedPagesModel> {
                 if(bookmarkedPagesModel.isCurrent(pageParameters)) {
                     item.add(new CssClassAppender("currentBookmark"));
                 }
+                item.add(new CssClassAppender("bookmarkDepth" + 
rootNode.getDepth()));
             }
         };
         container.add(listView);

http://git-wip-us.apache.org/repos/asf/isis/blob/7533ebd8/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/slide-panel.js
----------------------------------------------------------------------
diff --git 
a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/slide-panel.js
 
b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/slide-panel.js
index 4d8d601..c467bcc 100644
--- 
a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/slide-panel.js
+++ 
b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/slide-panel.js
@@ -19,21 +19,22 @@
 $(document).ready(function(){
  
     var showBookmarks = function(){
-        $('#panel').stop().animate(
+        $('#bookmarkedPagesSlidingDiv').stop().animate(
             {width:"400px", opacity:0.95}, 250, 
             function() {
                 $('.content').fadeIn('125');
             });
         $('.showPanelTab').animate({opacity: 0.5});
     };
+
     var hideBookmarks = function(){
         $('.content').fadeOut('125', 
             function() { 
-                $('#panel').stop().animate({width:"0", opacity:0.1}, 125);
+                $('#bookmarkedPagesSlidingDiv').stop().animate({width:"0", 
opacity:0.1}, 125);
             });
          $('.showPanelTab').animate({opacity: 1.0});
      };
 
     $('.showPanelTab').mouseenter(showBookmarks);
-    $('#panel').mouseleave(hideBookmarks);
+    $('#bookmarkedPagesSlidingDiv').mouseleave(hideBookmarks);
 });
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/7533ebd8/core/applib/src/main/java/org/apache/isis/applib/annotation/BookmarkPolicy.java
----------------------------------------------------------------------
diff --git 
a/core/applib/src/main/java/org/apache/isis/applib/annotation/BookmarkPolicy.java
 
b/core/applib/src/main/java/org/apache/isis/applib/annotation/BookmarkPolicy.java
index 2edd6cd..68d13b0 100644
--- 
a/core/applib/src/main/java/org/apache/isis/applib/annotation/BookmarkPolicy.java
+++ 
b/core/applib/src/main/java/org/apache/isis/applib/annotation/BookmarkPolicy.java
@@ -4,7 +4,7 @@ public enum BookmarkPolicy {
     /**
      * Can be bookmarked, and is a top-level 'root' (or parent) bookmark.
      */
-    ROOT,
+    AS_ROOT,
     /**
      * Can be bookmarked, but only as a child or some other parent/root 
bookmark
      */

http://git-wip-us.apache.org/repos/asf/isis/blob/7533ebd8/core/applib/src/main/java/org/apache/isis/applib/annotation/Bookmarkable.java
----------------------------------------------------------------------
diff --git 
a/core/applib/src/main/java/org/apache/isis/applib/annotation/Bookmarkable.java 
b/core/applib/src/main/java/org/apache/isis/applib/annotation/Bookmarkable.java
index 6b6f6e0..1d66d63 100644
--- 
a/core/applib/src/main/java/org/apache/isis/applib/annotation/Bookmarkable.java
+++ 
b/core/applib/src/main/java/org/apache/isis/applib/annotation/Bookmarkable.java
@@ -37,5 +37,5 @@ import java.lang.annotation.Target;
 @Retention(RetentionPolicy.RUNTIME)
 public @interface Bookmarkable {
     
-    BookmarkPolicy value() default BookmarkPolicy.ROOT;  
+    BookmarkPolicy value() default BookmarkPolicy.AS_ROOT;  
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/7533ebd8/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociationFilters.java
----------------------------------------------------------------------
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociationFilters.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociationFilters.java
index c112e05..59da48d 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociationFilters.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociationFilters.java
@@ -27,6 +27,7 @@ import 
org.apache.isis.core.commons.authentication.AuthenticationSession;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.consent.Consent;
 import org.apache.isis.core.metamodel.facets.hide.HiddenFacet;
+import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
 
 public class ObjectAssociationFilters {
 
@@ -44,6 +45,17 @@ public class ObjectAssociationFilters {
     };
 
     /**
+     * Filters only fields that are for reference properties (ie 1:1 
associations)
+     */
+    public final static Filter<ObjectAssociation> REFERENCE_PROPERTIES = new 
Filter<ObjectAssociation>() {
+        @Override
+        public boolean accept(final ObjectAssociation association) {
+            return association.isOneToOneAssociation() && 
+                   
!association.getSpecification().containsDoOpFacet(ValueFacet.class);
+        }
+    };
+    
+    /**
      * Filters only fields that are for properties (ie 1:1 associations)
      */
     public final static Filter<ObjectAssociation> 
WHERE_VISIBLE_IN_COLLECTION_TABLE = new Filter<ObjectAssociation>() {

Reply via email to