/*
* 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.eclipse.core.runtime.Status;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.*;
import org.jkiss.dbeaver.model.navigator.meta.DBXTreeNode;
import org.jkiss.dbeaver.model.net.DBWHandlerConfiguration;
import org.jkiss.dbeaver.model.runtime.DBRProgressListener;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.DBSObject;
import java.util.Collection;
/**
* DBNDataSource
*/
public class DBNDataSource extends DBNDatabaseNode implements IAdaptable
{
private final DBPDataSourceContainer dataSource;
private DBXTreeNode treeRoot;
public DBNDataSource(@NotNull DBNNode parentNode, @NotNull DBPDataSourceContainer dataSource)
{
super(parentNode);
this.dataSource = dataSource;
this.treeRoot = dataSource.getDriver().getNavigatorRoot();
registerNode();
}
@Override
public DBNNode getParentNode()
{
DBPDataSourceFolder folder = dataSource.getFolder();
if (folder != null) {
DBNLocalFolder localFolder = ((DBNProjectDatabases) super.getParentNode()).getFolderNode(folder);
if (localFolder != null) {
return localFolder;
}
}
return super.getParentNode();
}
@Override
protected void dispose(boolean reflect)
{
unregisterNode(reflect);
super.dispose(reflect);
}
@Override
public DBPDataSourceContainer getObject()
{
return dataSource;
}
@Override
public Object getValueObject()
{
return dataSource.getDataSource();
}
@Override
public String getNodeName()
{
return dataSource.getName();
}
@Override
public String getNodeDescription()
{
return dataSource.getDescription();
}
@Override
public String getNodeFullName()
{
return getNodeName();
}
@Override
public boolean isManagable()
{
return true;
}
@Override
public DBXTreeNode getMeta()
{
return treeRoot;
}
@Override
protected void reloadObject(DBRProgressMonitor monitor, DBSObject object) {
}
@Override
public boolean initializeNode(@Nullable DBRProgressMonitor monitor, DBRProgressListener onFinish)
{
if (!dataSource.isConnected()) {
dataSource.initConnection(monitor, onFinish);
} else {
if (onFinish != null) {
onFinish.onTaskFinished(Status.OK_STATUS);
}
}
return dataSource.isConnected();
}
@Override
public DBPImage getNodeIcon() {
DBPImage image = super.getNodeIcon();
boolean hasNetworkHandlers = hasNetworkHandlers();
if (dataSource.isConnectionReadOnly() || hasNetworkHandlers) {
if (image instanceof DBIconComposite) {
((DBIconComposite) image).setTopRight(hasNetworkHandlers ? DBIcon.OVER_EXTERNAL : null);
((DBIconComposite) image).setBottomLeft(dataSource.isConnectionReadOnly() ? DBIcon.OVER_LOCK : null);
} else {
image = new DBIconComposite(
image,
false,
null,
hasNetworkHandlers ? DBIcon.OVER_EXTERNAL : null,
dataSource.isConnectionReadOnly() ? DBIcon.OVER_LOCK : null,
null);
}
}
return image;
}
public boolean hasNetworkHandlers() {
for (DBWHandlerConfiguration handler : dataSource.getConnectionConfiguration().getDeclaredHandlers()) {
if (handler.isEnabled()) {
return true;
}
}
return false;
}
@Override
public <T> T getAdapter(Class<T> adapter) {
if (adapter == DBNDataSource.class) {
return adapter.cast(this);
} else if (DBPDataSourceContainer.class.isAssignableFrom(adapter)) {
return adapter.cast(dataSource);
}
return null;
}
@Override
@NotNull
public DBPDataSourceContainer getDataSourceContainer()
{
return dataSource;
}
@Override
public boolean supportsRename()
{
return true;
}
@Override
public void rename(DBRProgressMonitor monitor, String newName)
{
dataSource.setName(newName);
dataSource.persistConfiguration();
dataSource.fireEvent(new DBPEvent(DBPEvent.Action.OBJECT_UPDATE, dataSource, null));
}
@Override
protected void afterChildRead()
{
// Notify datasource listeners about state change.
// We make this action here because we can't update state in
// initializeNode if this action caused by readChildren.
// Because readChildren executes in separate job - this job reused by
// datasource connect job and it do not updates UI after connect because
// we need to read datasource children immediately.
// It breaks loading process. So we refresh datasource state manually
// right after children nodes read
dataSource.fireEvent(
new DBPEvent(DBPEvent.Action.OBJECT_UPDATE, dataSource, true));
}
@Override
public boolean supportsDrop(DBNNode otherNode)
{
return otherNode == null || otherNode instanceof DBNDataSource;
}
@Override
public void dropNodes(Collection<DBNNode> nodes) throws DBException
{
DBPDataSourceFolder folder = dataSource.getFolder();
for (DBNNode node : nodes) {
if (node instanceof DBNDataSource) {
if (!((DBNDataSource) node).setFolder(folder)) {
return;
}
}
}
DBNModel.updateConfigAndRefreshDatabases(this);
}
public boolean setFolder(DBPDataSourceFolder folder)
{
final DBPDataSourceFolder oldFolder = dataSource.getFolder();
if (oldFolder == folder) {
return false;
}
dataSource.setFolder(folder);
return true;
}
public DBNNode refreshNode(DBRProgressMonitor monitor, Object source) throws DBException
{
DBNNode node = super.refreshNode(monitor, source);
if (node == this) {
// Refresh succeeded. Let's fire event
dataSource.fireEvent(
new DBPEvent(DBPEvent.Action.OBJECT_UPDATE, dataSource));
}
return node;
}
@Override
public String toString() {
return dataSource.toString();
}
}