/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 Serge Rider (serge@jkiss.org)
*
* Licensed 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.jkiss.dbeaver.model.navigator;
import org.eclipse.core.runtime.IAdaptable;
import org.jkiss.code.NotNull;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.DBIcon;
import org.jkiss.dbeaver.model.DBPImage;
import org.jkiss.dbeaver.model.DBPNamedObject;
import org.jkiss.dbeaver.model.DBPPersistedObject;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.utils.CommonUtils;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* DBNNode
*/
public abstract class DBNNode implements DBPNamedObject, DBPPersistedObject, IAdaptable
{
static final Log log = Log.getLog(DBNNode.class);
public enum NodePathType {
resource,
folder,
database;
public String getPrefix() {
return name() + "://";
}
}
protected final DBNNode parentNode;
protected DBNNode()
{
this.parentNode = null;
}
protected DBNNode(DBNNode parentNode)
{
this.parentNode = parentNode;
}
public boolean isDisposed()
{
return false;
}
void dispose(boolean reflect)
{
}
public DBNModel getModel() {
return parentNode == null ? null : parentNode.getModel();
}
public DBNNode getParentNode()
{
return parentNode;
}
public boolean isLocked()
{
return getParentNode() != null && getParentNode().isLocked();
}
@Override
public boolean isPersisted()
{
return true;
}
public boolean isManagable()
{
return false;
}
@NotNull
@Override
public String getName()
{
return getNodeName();
}
public abstract String getNodeType();
public abstract String getNodeName();
public abstract String getNodeDescription();
public abstract DBPImage getNodeIcon();
@NotNull
public DBPImage getNodeIconDefault()
{
DBPImage image = getNodeIcon();
if (image == null) {
if (this.hasChildren(false)) {
return DBIcon.TREE_FOLDER;
} else {
return DBIcon.TREE_PAGE;
}
} else {
return image;
}
}
public String getNodeFullName()
{
StringBuilder pathName = new StringBuilder();
pathName.append(getNodeName());
for (DBNNode parent = getParentNode(); parent != null && !(parent instanceof DBNDataSource); parent = parent.getParentNode()) {
if (parent instanceof DBNDatabaseFolder) {
// skip folders
continue;
}
String parentName = parent.getNodeName();
if (!CommonUtils.isEmpty(parentName)) {
pathName.insert(0, '.').insert(0, parentName);
}
}
return pathName.toString();
}
public boolean hasChildren(boolean navigableOnly) {
return navigableOnly ? allowsNavigableChildren() : allowsChildren();
}
protected abstract boolean allowsChildren();
protected boolean allowsNavigableChildren() {
return allowsChildren();
}
public abstract DBNNode[] getChildren(DBRProgressMonitor monitor) throws DBException;
void clearNode(boolean reflect)
{
}
public boolean supportsRename()
{
return false;
}
public void rename(DBRProgressMonitor monitor, String newName) throws DBException
{
throw new DBException("Rename is not supported");
}
public boolean supportsDrop(DBNNode otherNode)
{
return false;
}
public void dropNodes(Collection<DBNNode> nodes) throws DBException
{
throw new DBException("Drop is not supported");
}
/**
* Refreshes node.
* If refresh cannot be done in this level then refreshes parent node.
* Do not actually changes navigation tree. If some underlying object is refreshed it must fire DB model
* event which will cause actual tree nodes refresh. Underlying object could present multiple times in
* navigation model - each occurrence will be refreshed then.
*
* @param monitor progress monitor
* @param source event source
* @return real refreshed node or null if nothing was refreshed
* @throws DBException on any internal exception
*/
public DBNNode refreshNode(DBRProgressMonitor monitor, Object source) throws DBException
{
if (this.getParentNode() != null) {
return this.getParentNode().refreshNode(monitor, source);
} else {
return null;
}
}
public boolean allowsOpen()
{
return true;
}
public boolean isChildOf(DBNNode node)
{
for (DBNNode parent = getParentNode(); parent != null; parent = parent.getParentNode()) {
if (parent == node) {
return true;
}
}
return false;
}
public boolean isFiltered()
{
return false;
}
/**
* Node item path in form [nodeType://]<path>
* nodeType can be 'resource', 'folder' or 'database'.
* If missing then 'database' will be used (backward compatibility).
*
* For resources and folders path is just a hierarchy path divided with / (slash).
*
* For database nodes path has form: type1=name1/type2=name2/...[/typeX]
* Where typeN is path element for particular database item, name is database object name.
* @return full item node path
*/
public abstract String getNodeItemPath();
@Override
public <T> T getAdapter(Class<T> adapter) {
return null;
}
static void sortNodes(List<? extends DBNNode> nodes) {
Collections.sort(nodes, new Comparator<DBNNode>() {
@Override
public int compare(DBNNode o1, DBNNode o2) {
return o1.getName().compareToIgnoreCase(o2.getName());
}
});
}
}