/*
* 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.viewer.wicket.model.models;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
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.commons.config.IsisConfiguration;
import org.apache.isis.core.metamodel.adapter.oid.RootOid;
public class BookmarkedPagesModel extends ModelAbstract<List<BookmarkTreeNode>> {
private static final long serialVersionUID = 1L;
private static final String MAX_SIZE_KEY = "isis.viewer.wicket.bookmarkedPages.maxSize";
private static final int MAX_SIZE_DEFAULT_VALUE = 15;
private final List<BookmarkTreeNode> rootNodes = Lists.newArrayList();
private transient PageParameters current;
public void bookmarkPage(final BookmarkableModel<?> bookmarkableModel) {
// hack: remove any garbage that might've got stored in 'rootNodes'
cleanUpGarbage(rootNodes);
final PageParameters candidatePP = bookmarkableModel.getPageParameters();
RootOid oid = BookmarkTreeNode.oidFrom(candidatePP);
if(oid == null) {
// ignore
return;
}
BookmarkTreeNode rootNode = null;
for (BookmarkTreeNode eachNode : rootNodes) {
if(eachNode.matches(bookmarkableModel)) {
rootNode = eachNode;
}
}
// MRU/LRU algorithm
if(rootNode != null) {
rootNodes.remove(rootNode);
rootNodes.add(0, rootNode);
current = candidatePP;
} else {
if (bookmarkableModel.hasAsRootPolicy()) {
rootNode = BookmarkTreeNode.newRoot(bookmarkableModel);
rootNodes.add(0, rootNode);
current = candidatePP;
}
}
trim(rootNodes, getMaxSize());
}
private int getMaxSize() {
return getConfiguration().getInteger(MAX_SIZE_KEY, MAX_SIZE_DEFAULT_VALUE);
}
private static void trim(List<?> list, int requiredSize) {
int numToRetain = Math.min(list.size(), requiredSize);
list.retainAll(list.subList(0, numToRetain));
}
@Override
protected List<BookmarkTreeNode> load() {
List<BookmarkTreeNode> depthFirstGraph = Lists.newArrayList();
List<BookmarkTreeNode> sortedNodes = Lists.newArrayList(rootNodes);
Collections.sort(sortedNodes, new BookmarkTreeNodeComparator(getSpecificationLoader()));
for (BookmarkTreeNode rootNode : sortedNodes) {
rootNode.appendGraphTo(depthFirstGraph);
}
return depthFirstGraph;
}
public boolean isCurrent(PageParameters pageParameters) {
return Objects.equal(current, pageParameters);
}
private static void cleanUpGarbage(List<BookmarkTreeNode> rootNodes) {
final Iterator<BookmarkTreeNode> iter = rootNodes.iterator();
while(iter.hasNext()) {
BookmarkTreeNode node = iter.next();
// think this is redundant...
if(node.getOidNoVer() == null) {
iter.remove();
}
}
}
public void clear() {
rootNodes.clear();
}
public boolean isEmpty() {
return rootNodes.isEmpty();
}
public void remove(BookmarkTreeNode rootNode) {
this.rootNodes.remove(rootNode);
}
public void remove(EntityModel entityModel) {
BookmarkTreeNode rootNode = null;
for (BookmarkTreeNode eachNode : rootNodes) {
if(eachNode.getOidNoVerStr().equals((entityModel).getObjectAdapterMemento().toString())) {
rootNode = eachNode;
}
}
if(rootNode != null) {
rootNodes.remove(rootNode);
}
}
// //////////////////////////////////////
protected IsisConfiguration getConfiguration() {
return getIsisSessionFactory().getConfiguration();
}
}