jaxx.runtime.swing.navigation.NavigationTreeModel Maven / Gradle / Ivy
/*
* *##%
* JAXX Runtime
* Copyright (C) 2008 - 2009 CodeLutin
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* ##%*
*/
package jaxx.runtime.swing.navigation;
import jaxx.runtime.JAXXContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import java.util.Enumeration;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Model of the tree used for a navigation tree.
*
* Il est composé de {@link NavigationTreeNode}
*
* @author chemit
* @since 1.7.2
*/
public class NavigationTreeModel extends DefaultTreeModel implements
NavigationModel{
static private final long serialVersionUID = 1L;
/**
* Logger
*/
static private final Log log = LogFactory.getLog(NavigationTreeModel.class);
/**
* The path separator used to build the {@link NavigationTreeNode#fullPath}.
*
* @see NavigationTreeNode#getNodePath()
* @see NavigationTreeNode#getFullPath()
*/
protected final String pathSeparator;
/**
* Context to retrieve beans
*/
private JAXXContext context;
public NavigationTreeModel(String pathSeparator, JAXXContext context) {
super(null);
this.pathSeparator = pathSeparator;
this.context = context;
}
/**
* @see NavigationModel#getRoot()
*/
@Override
public NavigationTreeNode getRoot() {
return (NavigationTreeNode) super.getRoot();
}
/**
* @see NavigationModel#findNode(String)
*/
@Override
public NavigationTreeNode findNode(String path) {
return findNode(getRoot(), path, (Pattern) null);
}
/**
* @see NavigationModel#findNode(String, String)
*/
@Override
public NavigationTreeNode findNode(String path, String regex) {
return findNode(getRoot(), path, regex);
}
/**
* @see NavigationModel#findNode(String, Pattern)
*/
@Override
public NavigationTreeNode findNode(String path, Pattern regex) {
return findNode(getRoot(), path, regex);
}
/**
* @see NavigationModel#findNode(NavigationTreeNode, String)
*/
@Override
public NavigationTreeNode findNode(NavigationTreeNode root, String path) {
return findNode(root, path, (Pattern) null);
}
/**
* @see NavigationModel#findNode(NavigationTreeNode, String, String)
*/
@Override
public NavigationTreeNode findNode(NavigationTreeNode root,
String path,
String regex) {
return findNode(root, path,
regex == null ? null : Pattern.compile(regex));
}
/**
* @see NavigationModel#findNode(NavigationTreeNode, String, Pattern)
*/
@Override
public NavigationTreeNode findNode(NavigationTreeNode root,
String path,
Pattern regex) {
if (regex != null) {
Matcher matcher = regex.matcher(path);
if (!matcher.matches() || matcher.groupCount() < 1) {
log.warn("no matching regex " + regex + " to " + path);
return null;
}
path = matcher.group(1);
if (log.isDebugEnabled()) {
log.debug("matching regex " + regex + " : " + path);
}
}
StringTokenizer stk = new StringTokenizer(path, pathSeparator);
NavigationTreeNode result = root;
// pas the first token (matches the root node)
if (root.isRoot() && stk.hasMoreTokens()) {
String rootPath = stk.nextToken();
if (!rootPath.equals(root.getNodePath())) {
return null;
}
}
while (stk.hasMoreTokens()) {
result = result.getChild(stk.nextToken());
}
return result;
}
/**
* @see NavigationModel#getContext()
*/
@Override
public JAXXContext getContext() {
return context;
}
/**
* @see NavigationModel#getBean(String)
*/
@Override
public Object getBean(String navigationPath) {
Object result;
NavigationTreeNode node = findNode(navigationPath, (Pattern) null);
result = getBean(node);
return result;
}
/**
* @see NavigationModel#getBean(NavigationTreeNode)
*/
@Override
public Object getBean(NavigationTreeNode node) {
if (node == null) {
return null;
//fixme should throw a NPE exception
//throw new NullPointerException("node can not be null");
}
return node.getBean(getContext());
}
/**
* @see NavigationModel#nodeChanged(TreeNode)
*/
@Override
public void nodeChanged(TreeNode node) {
nodeChanged(node, false);
if (log.isDebugEnabled()) {
log.debug(node);
}
}
/**
* @see NavigationModel#nodeStructureChanged(TreeNode)
*/
@Override
public void nodeStructureChanged(TreeNode node) {
NavigationTreeNode n = (NavigationTreeNode) node;
//TC-20091004 never launch a deep reload
reload(n, true);
super.nodeStructureChanged(node);
if (log.isDebugEnabled()) {
log.debug(node);
}
}
/**
* @see NavigationModel#nodeChanged(TreeNode, boolean)
*/
@Override
public void nodeChanged(TreeNode node, boolean deep) {
NavigationTreeNode n = (NavigationTreeNode) node;
//TC-20091004 never launch a deep clean, since we do a deep nodeChanged.
reload(n, deep);
super.nodeChanged(node);
}
protected void reload(NavigationTreeNode node) {
reload(node, false);
}
protected void reload(NavigationTreeNode node, boolean deep) {
if (node == null) {
return;
}
node.reload(getContext());
if (deep) {
Enumeration> childs = node.children();
while (childs.hasMoreElements()) {
NavigationTreeNode o = (NavigationTreeNode) childs.nextElement();
reload(o, true);
}
}
}
/**
* @see NavigationModel#getPathSeparator()
*/
@Override
public String getPathSeparator() {
return pathSeparator;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy