diff --git a/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF index c5d7dda090..ad07f74491 100644 --- a/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF +++ b/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF @@ -18,10 +18,11 @@ Require-Bundle: org.jkiss.dbeaver.model;visibility:=reexport, Export-Package: io.cloudbeaver, io.cloudbeaver.auth, io.cloudbeaver.auth.provider, - io.cloudbeaver.auth.provider.local, io.cloudbeaver.auth.provider.fa, + io.cloudbeaver.auth.provider.local, io.cloudbeaver.model, io.cloudbeaver.model.app, + io.cloudbeaver.model.rm, io.cloudbeaver.model.rm.local, io.cloudbeaver.model.session, io.cloudbeaver.model.user, diff --git a/server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/DBNAbstractResourceManagerNode.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNAbstractResourceManagerNode.java similarity index 82% rename from server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/DBNAbstractResourceManagerNode.java rename to server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNAbstractResourceManagerNode.java index 9de58b9fed..bc1fccd4e2 100644 --- a/server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/DBNAbstractResourceManagerNode.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNAbstractResourceManagerNode.java @@ -1,4 +1,4 @@ -package io.cloudbeaver.service.rm; +package io.cloudbeaver.model.rm; import org.jkiss.code.NotNull; import org.jkiss.dbeaver.model.DBPObjectWithDetails; @@ -8,10 +8,10 @@ import org.jkiss.utils.ArrayUtils; import java.util.Queue; -abstract class DBNAbstractResourceManagerNode extends DBNNode implements DBPObjectWithDetails { +public abstract class DBNAbstractResourceManagerNode extends DBNNode implements DBPObjectWithDetails { protected DBNResourceManagerResource[] children; - DBNAbstractResourceManagerNode(DBNNode parentNode) { + public DBNAbstractResourceManagerNode(DBNNode parentNode) { super(parentNode); } diff --git a/server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/DBNResourceManagerProject.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerProject.java similarity index 98% rename from server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/DBNResourceManagerProject.java rename to server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerProject.java index 9069beb325..d2c89efae9 100644 --- a/server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/DBNResourceManagerProject.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerProject.java @@ -15,7 +15,7 @@ * from DBeaver Corp. */ -package io.cloudbeaver.service.rm; +package io.cloudbeaver.model.rm; import org.jkiss.code.NotNull; import org.jkiss.code.Nullable; diff --git a/server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/DBNResourceManagerResource.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerResource.java similarity index 79% rename from server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/DBNResourceManagerResource.java rename to server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerResource.java index 9c3416828f..23245740a1 100644 --- a/server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/DBNResourceManagerResource.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerResource.java @@ -15,7 +15,7 @@ * from DBeaver Corp. */ -package io.cloudbeaver.service.rm; +package io.cloudbeaver.model.rm; import org.jkiss.code.NotNull; import org.jkiss.code.Nullable; @@ -30,6 +30,7 @@ import org.jkiss.dbeaver.model.rm.RMController; import org.jkiss.dbeaver.model.rm.RMProject; import org.jkiss.dbeaver.model.rm.RMResource; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; +import org.jkiss.utils.CommonUtils; import java.util.ArrayList; import java.util.List; @@ -83,7 +84,7 @@ public class DBNResourceManagerResource extends DBNAbstractResourceManagerNode { return children; } - private String getResourceFolder() { + public String getResourceFolder() { StringBuilder folder = new StringBuilder(); for (DBNNode parent = this; parent != null; parent = parent.getParentNode()) { if (parent instanceof DBNResourceManagerResource) { @@ -96,7 +97,7 @@ public class DBNResourceManagerResource extends DBNAbstractResourceManagerNode { return folder.length() == 0 ? null : folder.toString(); } - private RMProject getResourceProject() throws DBException { + public RMProject getResourceProject() throws DBException { for (DBNNode parent = getParentNode(); parent != null; parent = parent.getParentNode()) { if (parent instanceof DBNResourceManagerProject) { return ((DBNResourceManagerProject) parent).getProject(); @@ -124,7 +125,34 @@ public class DBNResourceManagerResource extends DBNAbstractResourceManagerNode { this.children = null; return this; } + @Override + public boolean supportsRename() { + return true; + } + @Override + public void rename(DBRProgressMonitor monitor, String newName) throws DBException { + try { + if (newName.indexOf('.') == -1) { + String resourceName = resource.getName(); + int indexOfExt = resourceName.indexOf('.'); + if (indexOfExt > 0) { + String ext = resourceName.substring(indexOfExt); + if (!CommonUtils.isEmpty(ext)) { + newName += "." + ext; + } + } + } + if (!newName.equals(resource.getName())) { + String oldPath = getResourceFolder(); + resource.setName(newName); + getResourceController().moveResource(getResourceProject().getId(), oldPath, getResourceFolder()); + + } + } catch (Exception e) { + throw new DBException("Can't rename resource", e); + } + } @Override public String toString() { return getNodeName(); diff --git a/server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/DBNResourceManagerRoot.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerRoot.java similarity index 97% rename from server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/DBNResourceManagerRoot.java rename to server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerRoot.java index f5aaf642ae..671bf40975 100644 --- a/server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/DBNResourceManagerRoot.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerRoot.java @@ -15,7 +15,7 @@ * from DBeaver Corp. */ -package io.cloudbeaver.service.rm; +package io.cloudbeaver.model.rm; import io.cloudbeaver.model.session.WebSession; import org.jkiss.dbeaver.DBException; @@ -38,7 +38,7 @@ public class DBNResourceManagerRoot extends DBNNode implements DBPHiddenObject, private DBNResourceManagerProject[] projects; private RMController resourceController; - DBNResourceManagerRoot(DBNProject parentNode) { + public DBNResourceManagerRoot(DBNProject parentNode) { super(parentNode); } diff --git a/server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/RMNavigatorUtils.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/RMNavigatorUtils.java similarity index 94% rename from server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/RMNavigatorUtils.java rename to server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/RMNavigatorUtils.java index bcea794d74..4034ba78b6 100644 --- a/server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/RMNavigatorUtils.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/RMNavigatorUtils.java @@ -1,4 +1,4 @@ -package io.cloudbeaver.service.rm; +package io.cloudbeaver.model.rm; import org.jkiss.dbeaver.model.rm.RMResource; diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java index aa1304b571..4fc62d95ba 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java @@ -258,8 +258,23 @@ public class LocalResourceController implements RMController { } @Override - public String moveResource(@NotNull String projectId, @NotNull String oldResourcePath, @NotNull String newResourcePath) throws DBException { - throw new DBCFeatureNotSupportedException(); + public String moveResource( + @NotNull String projectId, + @NotNull String oldResourcePath, + @NotNull String newResourcePath + ) throws DBException { + Path oldTargetPath = getTargetPath(projectId, oldResourcePath); + if (!Files.exists(oldTargetPath)) { + throw new DBException("Resource '" + oldTargetPath + "' doesn't exists"); + } + Path newTargetPath = getTargetPath(projectId, newResourcePath); + validateResourcePath(newTargetPath.toString()); + try { + Files.move(oldTargetPath, newTargetPath); + } catch (IOException e) { + throw new DBException("Error moving resource '" + oldResourcePath + "'", e); + } + return DEFAULT_CHANGE_ID; } @Override diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/WebNavigatorNodeInfo.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/WebNavigatorNodeInfo.java index ee69da357e..f3a66e24cb 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/WebNavigatorNodeInfo.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/WebNavigatorNodeInfo.java @@ -19,6 +19,8 @@ package io.cloudbeaver.service.navigator; import io.cloudbeaver.DBWebException; import io.cloudbeaver.WebServiceUtils; import io.cloudbeaver.model.WebPropertyInfo; +import io.cloudbeaver.model.rm.DBNAbstractResourceManagerNode; +import io.cloudbeaver.model.rm.DBNResourceManagerResource; import io.cloudbeaver.model.session.WebSession; import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.model.*; @@ -39,6 +41,12 @@ import java.util.List; * Web connection info */ public class WebNavigatorNodeInfo { + public static final String NODE_FEATURE_ITEM = "item"; + public static final String NODE_FEATURE_LEAF = "leaf"; + public static final String NODE_FEATURE_CONTAINER = "container"; + public static final String NODE_FEATURE_SHARED = "shared"; + public static final String NODE_FEATURE_CAN_DELETE = "canDelete"; + public static final String NODE_FEATURE_CAN_RENAME = "canRename"; private final WebSession session; private final DBNNode node; @@ -97,7 +105,9 @@ public class WebNavigatorNodeInfo { @Property public boolean isFolder() { - return node instanceof DBNContainer && !(node instanceof DBNDataSource); + return (node instanceof DBNContainer && !(node instanceof DBNDataSource)) + || (node instanceof DBNResourceManagerResource + && ((DBNResourceManagerResource) node).getResource().isFolder()); } @Property @@ -125,15 +135,15 @@ public class WebNavigatorNodeInfo { public String[] getFeatures() { List features = new ArrayList<>(); if (node instanceof DBNDatabaseItem) { - features.add("item"); + features.add(NODE_FEATURE_ITEM); DBSObject object = ((DBNDatabaseItem) node).getObject(); if (object instanceof DBSEntity || object instanceof DBSProcedure) { - features.add("leaf"); + features.add(NODE_FEATURE_LEAF); } } if (node instanceof DBNContainer) { - features.add("container"); + features.add(NODE_FEATURE_CONTAINER); } boolean isShared = false; if (node instanceof DBNDatabaseNode) { @@ -143,7 +153,7 @@ public class WebNavigatorNodeInfo { isShared = !projectName.equals(session.getUserId()); } if (isShared) { - features.add("shared"); + features.add(NODE_FEATURE_SHARED); } if (node instanceof DBNDatabaseNode) { @@ -152,14 +162,16 @@ public class WebNavigatorNodeInfo { DBEObjectMaker objectManager = DBWorkbench.getPlatform().getEditorsRegistry().getObjectManager( object.getClass(), DBEObjectMaker.class); if (objectManager != null && objectManager.canDeleteObject(object)) { - features.add("canDelete"); + features.add(NODE_FEATURE_CAN_DELETE); } if (objectManager instanceof DBEObjectRenamer && ((DBEObjectRenamer) objectManager).canRenameObject(object)) { if (!object.getDataSource().getContainer().getNavigatorSettings().isShowOnlyEntities()) { - features.add("canRename"); + features.add(NODE_FEATURE_CAN_RENAME); } } } + } else if (node instanceof DBNLocalFolder || node instanceof DBNAbstractResourceManagerNode) { + features.add(NODE_FEATURE_CAN_RENAME); } return features.toArray(new String[0]); diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java index 2525e2e040..e3c795b6a7 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java @@ -20,6 +20,9 @@ package io.cloudbeaver.service.navigator.impl; import io.cloudbeaver.DBWebException; import io.cloudbeaver.model.WebCommandContext; import io.cloudbeaver.model.WebConnectionInfo; +import io.cloudbeaver.model.rm.DBNAbstractResourceManagerNode; +import io.cloudbeaver.model.rm.DBNResourceManagerProject; +import io.cloudbeaver.model.rm.DBNResourceManagerResource; import io.cloudbeaver.model.session.WebSession; import io.cloudbeaver.service.navigator.DBWServiceNavigator; import io.cloudbeaver.service.navigator.WebCatalog; @@ -382,13 +385,28 @@ public class WebServiceNavigator implements DBWServiceNavigator { ((DBNDataSource) node).moveToFolder(folderNode.getOwnerProject(), folder); session.getSingletonProject().getDataSourceRegistry().updateDataSource( ((DBNDataSource) node).getDataSourceContainer()); + } else if (node instanceof DBNResourceManagerResource) { + boolean rmNewNode = folderNode instanceof DBNAbstractResourceManagerNode; + DBNResourceManagerResource rmOldNode = (DBNResourceManagerResource) node; + if (!rmNewNode) { + throw new DBWebException("Navigator node '" + folderNodePath + "' is not a resource manager node"); + } + // Get project id from node + String projectId = rmOldNode.getResourceProject().getId(); + // Get paths from nodes + String newPath = rmOldNode.getResource().getName(); + if (folderNode instanceof DBNResourceManagerResource) { + newPath = ((DBNResourceManagerResource) folderNode).getResourceFolder() + "/" + newPath; + } + String resourcePath = rmOldNode.getResourceFolder(); + session.getRmController().moveResource(projectId, resourcePath, newPath); } else { throw new DBWebException("Navigator node '" + path + "' is not a data source node"); } } return true; } catch (DBException e) { - throw new DBWebException("Error deleting navigator nodes " + nodePaths, e); + throw new DBWebException("Error moving navigator nodes " + nodePaths, e); } } @@ -424,5 +442,4 @@ public class WebServiceNavigator implements DBWServiceNavigator { } return executionContext; } - } diff --git a/server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/RMNavigatorModelExtender.java b/server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/RMNavigatorModelExtender.java index 196580c1b8..cf8ec16768 100644 --- a/server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/RMNavigatorModelExtender.java +++ b/server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/RMNavigatorModelExtender.java @@ -17,6 +17,7 @@ package io.cloudbeaver.service.rm; +import io.cloudbeaver.model.rm.DBNResourceManagerRoot; import io.cloudbeaver.utils.WebAppUtils; import org.jkiss.code.NotNull; import org.jkiss.dbeaver.model.navigator.DBNModelExtender;