/* * 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.ui.resources.bookmarks; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.jkiss.code.NotNull; import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.core.CoreMessages; import org.jkiss.dbeaver.core.DBeaverCore; import org.jkiss.dbeaver.core.DBeaverUI; import org.jkiss.dbeaver.model.DBPDataSourceContainer; import org.jkiss.dbeaver.model.navigator.*; import org.jkiss.dbeaver.model.runtime.DBRProgressListener; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; import org.jkiss.dbeaver.model.runtime.DBRRunnableWithProgress; import org.jkiss.dbeaver.runtime.ui.DBUserInterface; import org.jkiss.dbeaver.ui.UIUtils; import org.jkiss.dbeaver.ui.actions.navigator.NavigatorHandlerObjectOpen; import org.jkiss.dbeaver.ui.resources.AbstractResourceHandler; import org.jkiss.dbeaver.utils.ContentUtils; import org.jkiss.dbeaver.utils.RuntimeUtils; import org.jkiss.utils.ArrayUtils; import org.jkiss.utils.CommonUtils; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collection; import java.util.List; /** * Bookmarks handler */ public class BookmarksHandlerImpl extends AbstractResourceHandler { private static final String BOOKMARK_EXT = "bm"; //$NON-NLS-1$ public static IFolder getBookmarksFolder(IProject project, boolean forceCreate) { return DBeaverCore.getInstance().getProjectRegistry().getResourceDefaultRoot(project, BookmarksHandlerImpl.class, forceCreate); } @Override public int getFeatures(IResource resource) { if (resource instanceof IFile) { return FEATURE_OPEN | FEATURE_DELETE | FEATURE_RENAME; } return super.getFeatures(resource); } @NotNull @Override public String getTypeName(@NotNull IResource resource) { if (resource instanceof IFolder) { return "bookmark folder"; //$NON-NLS-1$ } else { return "bookmark"; //$NON-NLS-1$ } } @NotNull @Override public String getResourceNodeName(@NotNull IResource resource) { if (resource.getParent() instanceof IProject) { return "Bookmarks"; } else { return super.getResourceNodeName(resource); } } @NotNull @Override public DBNResource makeNavigatorNode(@NotNull DBNNode parentNode, @NotNull IResource resource) throws CoreException, DBException { if (resource instanceof IFile) { return new DBNBookmark(parentNode, resource, this); } else { return new DBNBookmarkFolder(parentNode, resource, this); } } @Override public void openResource(@NotNull final IResource resource) throws CoreException, DBException { if (!(resource instanceof IFile)) { return; } final DBNProject projectNode = DBeaverCore.getInstance().getNavigatorModel().getRoot().getProject(resource.getProject()); if (projectNode == null) { throw new DBException("Can't find project node for '" + resource.getProject().getName() + "'"); //$NON-NLS-2$ } final BookmarkStorage storage = new BookmarkStorage((IFile) resource, false); try { final DBPDataSourceContainer dataSourceContainer = projectNode.getDatabases().getDataSourceRegistry().getDataSource(storage.getDataSourceId()); if (dataSourceContainer == null) { throw new DBException("Can't find datasource '" + storage.getDataSourceId() + "'"); //$NON-NLS-2$ } final DBNDataSource dsNode = (DBNDataSource)DBeaverCore.getInstance().getNavigatorModel().getNodeByObject(dataSourceContainer); if (dsNode == null) { throw new DBException("Can't find datasource node for '" + dataSourceContainer.getName() + "'"); //$NON-NLS-2$ } dsNode.initializeNode(null, new DBRProgressListener() { @Override public void onTaskFinished(IStatus status) { if (status.isOK()) { DBeaverUI.syncExec(new Runnable() { @Override public void run() { openNodeByPath(dsNode, (IFile) resource, storage); } }); } else { DBUserInterface.getInstance().showError( "Open bookmark", "Can't open bookmark", status); } } }); } finally { storage.dispose(); } } private void openNodeByPath(final DBNDataSource dsNode, final IFile file, final BookmarkStorage storage) { try { DBeaverUI.runInProgressService(new DBRRunnableWithProgress() { @Override public void run(DBRProgressMonitor monitor) throws InvocationTargetException, InterruptedException { try { DBNNode currentNode = dsNode; final Collection<String> dataSourcePath = storage.getDataSourcePath(); for (String path : dataSourcePath) { DBNNode nextChild = null; final DBNNode[] children = currentNode.getChildren(monitor); if (!ArrayUtils.isEmpty(children)) { for (DBNNode node : children) { if (path.equals(node.getNodeName())) { nextChild = node; break; } } } if (nextChild == null) { throw new DBException("Can't find node '" + path + "' in '" + currentNode.getNodeFullName() + "'"); //$NON-NLS-2$ //$NON-NLS-3$ } currentNode = nextChild; } if (currentNode instanceof DBNDatabaseNode) { // Update bookmark image storage.setImage(currentNode.getNodeIconDefault()); file.setContents(storage.serialize(), true, false, RuntimeUtils.getNestedMonitor(monitor)); // Open entity editor final DBNDatabaseNode databaseNode = (DBNDatabaseNode) currentNode; DBeaverUI.syncExec(new Runnable() { @Override public void run() { NavigatorHandlerObjectOpen.openEntityEditor(databaseNode, null, DBeaverUI.getActiveWorkbenchWindow()); } }); } else if (currentNode != null) { throw new DBException("Node '" + currentNode.getNodeFullName() + "' is not a database object"); } else { throw new DBException("Can't find database node by path"); } } catch (Exception e) { throw new InvocationTargetException(e); } } }); } catch (InvocationTargetException e) { UIUtils.showErrorDialog(null, CoreMessages.model_project_open_bookmark, CoreMessages.model_project_cant_open_bookmark, e.getTargetException()); } catch (InterruptedException e) { // do nothing } } public static void createBookmark(final DBNDatabaseNode node, String title, IFolder folder) throws DBException { if (folder == null) { final IProject project = node.getOwnerProject(); if (project != null) { folder = getBookmarksFolder(project, true); } } if (folder == null) { throw new DBException("Can't detect folder for bookmark"); } IFile file = ContentUtils.getUniqueFile( folder, CommonUtils.escapeFileName(title), BOOKMARK_EXT); updateBookmark(node, title, file); } private static void updateBookmark(DBNDatabaseNode node, String title, IFile file) throws DBException { if (CommonUtils.isEmpty(title)) { title = node.getNodeName(); } List<String> nodePath = new ArrayList<>(); for (DBNNode parent = node; !(parent instanceof DBNDataSource); parent = parent.getParentNode()) { nodePath.add(0, parent.getNodeName()); } String dsId = null; if (node.getObject() != null && node.getObject().getDataSource() != null) { dsId = node.getObject().getDataSource().getContainer().getId(); } BookmarkStorage storage = new BookmarkStorage( title, node.getNodeType() + " " + node.getNodeName(), //$NON-NLS-1$ node.getNodeIconDefault(), dsId, nodePath); try { InputStream data = storage.serialize(); file.create(data, true, new NullProgressMonitor()); } catch (Exception e) { throw new DBException("Error saving bookmark", e); } } }