/* * 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.actions.navigator; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.ui.IWorkbenchWindow; import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.core.DBeaverCore; import org.jkiss.dbeaver.core.DBeaverUI; import org.jkiss.dbeaver.model.DBPRefreshableObject; import org.jkiss.dbeaver.model.edit.DBEObjectMaker; import org.jkiss.dbeaver.model.edit.DBEObjectManager; import org.jkiss.dbeaver.model.navigator.DBNContainer; import org.jkiss.dbeaver.model.navigator.DBNDatabaseNode; import org.jkiss.dbeaver.model.navigator.DBNNode; import org.jkiss.dbeaver.model.runtime.AbstractJob; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; import org.jkiss.dbeaver.model.struct.DBSObject; import org.jkiss.dbeaver.registry.editor.EntityEditorsRegistry; import org.jkiss.dbeaver.ui.UIUtils; import org.jkiss.dbeaver.ui.editors.IDatabaseEditor; import org.jkiss.dbeaver.ui.editors.entity.EntityEditor; import org.jkiss.dbeaver.ui.editors.entity.EntityEditorInput; import org.jkiss.dbeaver.ui.navigator.database.DatabaseNavigatorView; import org.jkiss.dbeaver.utils.GeneralUtils; public abstract class NavigatorHandlerObjectCreateBase extends NavigatorHandlerObjectBase { protected boolean createNewObject(final IWorkbenchWindow workbenchWindow, DBNNode element, DBNDatabaseNode copyFrom) { try { DBNContainer container = null; if (element instanceof DBNContainer) { container = (DBNContainer) element; } else { DBNNode parentNode = element.getParentNode(); if (parentNode instanceof DBNContainer) { container = (DBNContainer) parentNode; } } if (container == null) { throw new DBException("Can't detect container for '" + element.getNodeName() + "'"); } Class<?> childType = container.getChildrenClass(); if (childType == null) { throw new DBException("Can't determine child element type for container '" + container + "'"); } if (childType == IProject.class) { return NavigatorHandlerProjectCreate.createNewProject(workbenchWindow); } DBSObject sourceObject = copyFrom == null ? null : copyFrom.getObject(); // Do not check for type - manager must do it. Potentially we can copy anything into anything. // if (sourceObject != null && !childType.isAssignableFrom(sourceObject.getClass())) { // throw new DBException("Can't create '" + childType.getName() + "' from '" + sourceObject.getClass().getName() + "'"); // } final EntityEditorsRegistry editorsRegistry = EntityEditorsRegistry.getInstance(); DBEObjectManager<?> objectManager = editorsRegistry.getObjectManager(childType); if (objectManager == null) { throw new DBException("Object manager not found for type '" + childType.getName() + "'"); } DBEObjectMaker objectMaker = (DBEObjectMaker) objectManager; final boolean openEditor = (objectMaker.getMakerOptions() & DBEObjectMaker.FEATURE_EDITOR_ON_CREATE) != 0; CommandTarget commandTarget = getCommandTarget( workbenchWindow, container, childType, openEditor); final Object parentObject = container.getValueObject(); createDatabaseObject(commandTarget, objectMaker, parentObject, sourceObject); } catch (Throwable e) { UIUtils.showErrorDialog(workbenchWindow.getShell(), "Create object", null, e); return false; } return true; } private <OBJECT_TYPE extends DBSObject, CONTAINER_TYPE> void createDatabaseObject( CommandTarget commandTarget, DBEObjectMaker<OBJECT_TYPE, CONTAINER_TYPE> objectMaker, CONTAINER_TYPE parentObject, DBSObject sourceObject) throws DBException { final CreateJob<OBJECT_TYPE, CONTAINER_TYPE> job = new CreateJob<>(commandTarget, objectMaker, parentObject, sourceObject); job.schedule(); } static class CreateJob<OBJECT_TYPE extends DBSObject, CONTAINER_TYPE> extends AbstractJob { private final CommandTarget commandTarget; private final DBEObjectMaker<OBJECT_TYPE, CONTAINER_TYPE> objectMaker; private final CONTAINER_TYPE parentObject; private final DBSObject sourceObject; private OBJECT_TYPE newObject; public CreateJob(CommandTarget commandTarget, DBEObjectMaker<OBJECT_TYPE, CONTAINER_TYPE> objectMaker, CONTAINER_TYPE parentObject, DBSObject sourceObject) { super("Create new database object with " + objectMaker.getClass().getSimpleName()); this.commandTarget = commandTarget; this.objectMaker = objectMaker; this.parentObject = parentObject; this.sourceObject = sourceObject; } @Override protected IStatus run(DBRProgressMonitor monitor) { try { newObject = objectMaker.createNewObject(monitor, commandTarget.getContext(), parentObject, sourceObject); if (newObject == null) { return Status.CANCEL_STATUS; } if ((objectMaker.getMakerOptions() & DBEObjectMaker.FEATURE_SAVE_IMMEDIATELY) != 0) { // Save object manager's content commandTarget.getContext().saveChanges(monitor); // Refresh new object (so it can load some props from database) if (newObject instanceof DBPRefreshableObject) { final DBNDatabaseNode newChild = DBeaverCore.getInstance().getNavigatorModel().findNode(newObject); if (newChild != null) { newChild.refreshNode(monitor, this); newObject = (OBJECT_TYPE) newChild.getObject(); } } } // Open object in UI thread DBeaverUI.syncExec(new Runnable() { @Override public void run() { openNewObject(); } }); return Status.OK_STATUS; } catch (Exception e) { return GeneralUtils.makeExceptionStatus(e); } } private void openNewObject() { IWorkbenchWindow workbenchWindow = DBeaverUI.getActiveWorkbenchWindow(); try { final boolean openEditor = (objectMaker.getMakerOptions() & DBEObjectMaker.FEATURE_EDITOR_ON_CREATE) != 0; final DBNDatabaseNode newChild = DBeaverCore.getInstance().getNavigatorModel().findNode(newObject); if (newChild != null) { DatabaseNavigatorView view = UIUtils.findView(workbenchWindow, DatabaseNavigatorView.class); if (view != null) { view.showNode(newChild); } IDatabaseEditor editor = commandTarget.getEditor(); if (editor != null) { // Just activate existing editor workbenchWindow.getActivePage().activate(editor); } else if (openEditor) { // Open new one with existing context EntityEditorInput editorInput = new EntityEditorInput( newChild, commandTarget.getContext()); workbenchWindow.getActivePage().openEditor( editorInput, EntityEditor.class.getName()); } } else { throw new DBException("Can't find node corresponding to new object"); } } catch (Throwable e) { UIUtils.showErrorDialog(workbenchWindow.getShell(), "Create object", null, e); } } } }