From d4c04a3d572a0f1e3d66326451edc9f61102ff1c Mon Sep 17 00:00:00 2001 From: Valeriy Svydenko Date: Tue, 5 Jun 2018 15:36:05 +0300 Subject: [PATCH] use jdt.ls to support Rename refactoring (#9636) Signed-off-by: Valeriy Svydenko --- .../che/ide/api/resources/Container.java | 19 + .../che/ide/resources/impl/ContainerImpl.java | 5 + .../ide/resources/impl/ResourceManager.java | 4 + .../che-plugin-java-ext-lang-client/pom.xml | 8 + .../diagnostics/PomDiagnosticsRequestor.java | 4 +- .../RefactoringActionDelegate.java | 21 + .../move/wizard/MovePresenter.java | 9 +- .../refactoring/preview/PreviewNode.java | 131 +++ .../refactoring/preview/PreviewPresenter.java | 354 +++++--- .../refactoring/preview/PreviewView.java | 22 +- .../refactoring/preview/PreviewViewImpl.java | 46 +- .../preview/StringStreamEditor.java | 121 +++ .../rename/JavaRefactoringRename.java | 377 ++++---- .../rename/RenameRefactoringAction.java | 36 +- .../rename/wizard/RenamePresenter.java | 478 ++++------- .../refactoring/rename/wizard/RenameView.java | 6 +- .../rename/wizard/RenameViewImpl.java | 15 +- .../SimilarNamesConfigurationPresenter.java | 8 +- .../SimilarNamesConfigurationView.java | 4 +- .../SimilarNamesConfigurationViewImpl.java | 10 +- .../JavaLanguageExtensionServiceClient.java | 72 +- .../preview/PreviewPresenterTest.java | 257 ------ .../rename/JavaRefactoringRenameTest.java | 471 ---------- .../rename/wizard/RenamePresenterTest.java | 812 ------------------ ...imilarNamesConfigurationPresenterTest.java | 4 +- ...SimilarNamesConfigurationViewImplTest.java | 6 +- .../che/ide/ext/java/shared/Constants.java | 5 + .../che-plugin-java-server/pom.xml | 4 + .../java/languageserver/JavaLSWrapper.java | 10 + .../JavaLanguageServerExtensionService.java | 109 +++ .../quickassist/ApplyWorkspaceEditAction.java | 187 +++- 31 files changed, 1320 insertions(+), 2295 deletions(-) create mode 100644 plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/RefactoringActionDelegate.java create mode 100644 plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/preview/PreviewNode.java create mode 100644 plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/preview/StringStreamEditor.java delete mode 100644 plugins/plugin-java/che-plugin-java-ext-lang-client/src/test/java/org/eclipse/che/ide/ext/java/client/refactoring/preview/PreviewPresenterTest.java delete mode 100644 plugins/plugin-java/che-plugin-java-ext-lang-client/src/test/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/JavaRefactoringRenameTest.java delete mode 100644 plugins/plugin-java/che-plugin-java-ext-lang-client/src/test/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/RenamePresenterTest.java diff --git a/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/resources/Container.java b/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/resources/Container.java index 6a26e8508c70..b96277e2c48e 100644 --- a/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/resources/Container.java +++ b/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/resources/Container.java @@ -125,6 +125,25 @@ public interface Container extends Resource { */ Promise> getContainer(String relativePath); + /** + * Returns the {@code Promise} with handle to the resource identified by the given path in this + * container. + * + *

The supplied path should represent relative path to resource. + * + * @param relativePath the path of the member resource + * @return the {@code Promise} with the handle of the member resource + * @throws IllegalStateException if during resource search failed has been occurred. Reasons + * include: + *

    + *
  • Resource with path '/project_path' doesn't exists + *
  • Resource with path '/project_path' isn't a project + *
+ * + * @see #getFile(Path) + */ + Promise> getResource(Path relativePath); + /** * Returns the {@code Promise} with array of existing member resources (projects, folders and * files) in this resource, in particular order. Order is organized by alphabetic resource name diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/resources/impl/ContainerImpl.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/resources/impl/ContainerImpl.java index 5937b3987203..f28eefec050d 100644 --- a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/resources/impl/ContainerImpl.java +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/resources/impl/ContainerImpl.java @@ -76,6 +76,11 @@ public Promise> getContainer(String relativePath) { return resourceManager.getContainer(getLocation().append(relativePath)); } + @Override + public Promise> getResource(Path relativePath) { + return resourceManager.getResource(getLocation().append(relativePath)); + } + /** {@inheritDoc} */ @Override public Promise getChildren(final boolean forceUpdate) { diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/resources/impl/ResourceManager.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/resources/impl/ResourceManager.java index e6438bdd7549..a3fc7426aa0f 100644 --- a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/resources/impl/ResourceManager.java +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/resources/impl/ResourceManager.java @@ -789,6 +789,10 @@ Promise> getContainer(final Path absolutePath) { }); } + protected Promise> getResource(final Path absolutePath) { + return findResource(absolutePath); + } + protected Promise> getFile(final Path absolutePath) { final Optional resourceOptional = store.getResource(absolutePath); diff --git a/plugins/plugin-java/che-plugin-java-ext-lang-client/pom.xml b/plugins/plugin-java/che-plugin-java-ext-lang-client/pom.xml index 5910cfdbaca8..8fe79ba4b86d 100644 --- a/plugins/plugin-java/che-plugin-java-ext-lang-client/pom.xml +++ b/plugins/plugin-java/che-plugin-java-ext-lang-client/pom.xml @@ -151,6 +151,10 @@ org.eclipse.lsp4j org.eclipse.lsp4j + + org.eclipse.lsp4j + org.eclipse.lsp4j.jsonrpc + org.vectomatic lib-gwt-svg @@ -316,6 +320,10 @@ org.eclipse.che.jdt.ls.extension.api.dto + + org.eclipse.che.jdt.ls.extension.api.dto.CheResourceChange + org.eclipse.che.jdt.ls.extension.api.dto.CheWorkspaceEdit + org.eclipse.che.jdt.ls.extension.api.dto.LinearRange diff --git a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/diagnostics/PomDiagnosticsRequestor.java b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/diagnostics/PomDiagnosticsRequestor.java index e657a891e0fc..f40eb8ccef53 100644 --- a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/diagnostics/PomDiagnosticsRequestor.java +++ b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/diagnostics/PomDiagnosticsRequestor.java @@ -32,7 +32,7 @@ public class PomDiagnosticsRequestor { @Inject public PomDiagnosticsRequestor( final EventBus eventBus, - DtoBuildHelper buildHelper, + final DtoBuildHelper buildHelper, final JavaLanguageExtensionServiceClient service) { eventBus.addHandler( EditorOpenedEvent.TYPE, @@ -40,7 +40,7 @@ public PomDiagnosticsRequestor( @Override public void onEditorOpened(EditorOpenedEvent event) { String uri = buildHelper.getUri(event.getFile()); - if (uri.endsWith(POM_FILE)) { + if (!uri.endsWith(POM_FILE)) { return; } new Timer() { diff --git a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/RefactoringActionDelegate.java b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/RefactoringActionDelegate.java new file mode 100644 index 000000000000..6ef83588de66 --- /dev/null +++ b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/RefactoringActionDelegate.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2012-2018 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.ide.ext.java.client.refactoring; + +/** + * Describes actions which should be supported by refactoring wizards. + * + * @author Valeriy Svydenko + */ +public interface RefactoringActionDelegate { + /** Closes wizard's window. */ + void closeWizard(); +} diff --git a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/move/wizard/MovePresenter.java b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/move/wizard/MovePresenter.java index 5d15842fc4e0..dba3f866f825 100644 --- a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/move/wizard/MovePresenter.java +++ b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/move/wizard/MovePresenter.java @@ -40,6 +40,7 @@ import org.eclipse.che.ide.ext.java.client.JavaLocalizationConstant; import org.eclipse.che.ide.ext.java.client.navigation.service.JavaNavigationService; import org.eclipse.che.ide.ext.java.client.refactoring.RefactorInfo; +import org.eclipse.che.ide.ext.java.client.refactoring.RefactoringActionDelegate; import org.eclipse.che.ide.ext.java.client.refactoring.RefactoringUpdater; import org.eclipse.che.ide.ext.java.client.refactoring.preview.PreviewPresenter; import org.eclipse.che.ide.ext.java.client.refactoring.service.RefactoringServiceClient; @@ -61,7 +62,7 @@ * @author Valeriy Svydenko */ @Singleton -public class MovePresenter implements MoveView.ActionDelegate { +public class MovePresenter implements MoveView.ActionDelegate, RefactoringActionDelegate { private final MoveView view; private final RefactoringUpdater refactoringUpdater; private final EditorAgent editorAgent; @@ -364,4 +365,10 @@ private void showErrorMessage(RefactoringStatus arg) { view.setEnableAcceptButton(false); view.setEnablePreviewButton(false); } + + @Override + public void closeWizard() { + view.close(); + onCancelButtonClicked(); + } } diff --git a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/preview/PreviewNode.java b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/preview/PreviewNode.java new file mode 100644 index 000000000000..a3d11e7cc35c --- /dev/null +++ b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/preview/PreviewNode.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2012-2018 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.ide.ext.java.client.refactoring.preview; + +import java.util.ArrayList; +import java.util.List; +import org.eclipse.lsp4j.ResourceChange; +import org.eclipse.lsp4j.TextEdit; +import org.eclipse.lsp4j.jsonrpc.messages.Either; + +/** + * Describes a node from the tree of changes in Preview page. + * + * @author Valeriy Svydenko + */ +public class PreviewNode { + private String id; + private String description; + private boolean enable; + private Either data; + private List children; + private PreviewNode parent; + private String uri; + + public PreviewNode() { + this.children = new ArrayList<>(); + } + + /** Returns id of node. */ + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + /** Returns description which describes current node. */ + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + /** Returns {@code true} if node is chose otherwise returns {@code false}. */ + public boolean isEnable() { + return enable; + } + + public void setEnable(boolean enable) { + this.enable = enable; + } + + /** Returns data of current node it can be {@link ResourceChange} or {@link TextEdit}. */ + public Either getData() { + return data; + } + + public void setData(Either data) { + this.data = data; + } + + /** Returns list of children. */ + public List getChildren() { + return children; + } + + public void setChildren(List children) { + this.children = children; + } + + /** Returns parent node if current node is leaf or null if it isn't. */ + public PreviewNode getParent() { + return parent; + } + + public void setParent(PreviewNode parent) { + this.parent = parent; + } + + public boolean hasParent() { + return parent != null; + } + + /** Returns uri of the resource which is related to current change. */ + public String getUri() { + return uri; + } + + public void setUri(String uri) { + this.uri = uri; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + PreviewNode other = (PreviewNode) obj; + if (this.children == null) { + if (other.children != null) return false; + } else if (!this.children.equals(other.children)) return false; + if (this.id == null) { + if (other.id != null) return false; + } else if (!this.id.equals(other.id)) return false; + if (this.uri == null) { + if (other.uri != null) return false; + } else if (!this.uri.equals(other.uri)) return false; + return true; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.children == null) ? 0 : this.children.hashCode()); + result = prime * result + ((this.id == null) ? 0 : this.id.hashCode()); + result = prime * result + ((this.uri == null) ? 0 : this.uri.hashCode()); + return result; + } +} diff --git a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/preview/PreviewPresenter.java b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/preview/PreviewPresenter.java index 7f2659902cf6..650cad9aae4f 100644 --- a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/preview/PreviewPresenter.java +++ b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/preview/PreviewPresenter.java @@ -10,31 +10,31 @@ */ package org.eclipse.che.ide.ext.java.client.refactoring.preview; -import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus.OK; +import static java.util.stream.Collectors.toList; +import com.google.common.base.Optional; +import com.google.gwt.dom.client.Document; import com.google.inject.Inject; -import com.google.inject.Provider; import com.google.inject.Singleton; +import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; -import org.eclipse.che.api.promises.client.Operation; -import org.eclipse.che.api.promises.client.OperationException; +import java.util.Map; import org.eclipse.che.api.promises.client.Promise; -import org.eclipse.che.ide.api.editor.EditorAgent; -import org.eclipse.che.ide.api.editor.EditorPartPresenter; -import org.eclipse.che.ide.api.editor.texteditor.TextEditor; -import org.eclipse.che.ide.api.filewatcher.ClientServerEventService; +import org.eclipse.che.ide.api.app.AppContext; +import org.eclipse.che.ide.api.resources.Container; +import org.eclipse.che.ide.api.resources.File; import org.eclipse.che.ide.dto.DtoFactory; import org.eclipse.che.ide.ext.java.client.refactoring.RefactorInfo; -import org.eclipse.che.ide.ext.java.client.refactoring.RefactoringUpdater; -import org.eclipse.che.ide.ext.java.client.refactoring.move.wizard.MovePresenter; -import org.eclipse.che.ide.ext.java.client.refactoring.rename.wizard.RenamePresenter; -import org.eclipse.che.ide.ext.java.client.refactoring.service.RefactoringServiceClient; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.ChangeEnabledState; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.ChangeInfo; +import org.eclipse.che.ide.ext.java.client.refactoring.RefactoringActionDelegate; import org.eclipse.che.ide.ext.java.shared.dto.refactoring.ChangePreview; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringChange; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringPreview; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringSession; +import org.eclipse.che.ide.resource.Path; +import org.eclipse.che.jdt.ls.extension.api.dto.CheResourceChange; +import org.eclipse.che.jdt.ls.extension.api.dto.CheWorkspaceEdit; +import org.eclipse.che.plugin.languageserver.ide.editor.quickassist.ApplyWorkspaceEditAction; +import org.eclipse.lsp4j.ResourceChange; +import org.eclipse.lsp4j.TextEdit; +import org.eclipse.lsp4j.jsonrpc.messages.Either; /** * @author Dmitry Shnurenko @@ -44,55 +44,30 @@ public class PreviewPresenter implements PreviewView.ActionDelegate { private final PreviewView view; - private final Provider renamePresenterProvider; + private final AppContext appContext; + private final ApplyWorkspaceEditAction applyWorkspaceEditAction; private final DtoFactory dtoFactory; - private final EditorAgent editorAgent; - private final RefactoringUpdater refactoringUpdater; - private final RefactoringServiceClient refactoringService; - private final Provider movePresenterProvider; - private final ClientServerEventService clientServerEventService; - private RefactorInfo refactorInfo; - private RefactoringSession session; + private Map fileNodes; + private CheWorkspaceEdit workspaceEdit; + private RefactoringActionDelegate refactoringActionDelegate; @Inject public PreviewPresenter( PreviewView view, - Provider movePresenterProvider, - Provider renamePresenterProvider, - DtoFactory dtoFactory, - EditorAgent editorAgent, - RefactoringUpdater refactoringUpdater, - RefactoringServiceClient refactoringService, - ClientServerEventService clientServerEventService) { + AppContext appContext, + ApplyWorkspaceEditAction applyWorkspaceEditAction, + DtoFactory dtoFactory) { this.view = view; - this.renamePresenterProvider = renamePresenterProvider; + this.appContext = appContext; + this.applyWorkspaceEditAction = applyWorkspaceEditAction; this.dtoFactory = dtoFactory; - this.editorAgent = editorAgent; - this.refactoringUpdater = refactoringUpdater; - this.refactoringService = refactoringService; - this.clientServerEventService = clientServerEventService; this.view.setDelegate(this); - this.movePresenterProvider = movePresenterProvider; + fileNodes = new LinkedHashMap<>(); } public void show(String refactoringSessionId, RefactorInfo refactorInfo) { - this.refactorInfo = refactorInfo; - - session = dtoFactory.createDto(RefactoringSession.class); - session.setSessionId(refactoringSessionId); - - refactoringService - .getRefactoringPreview(session) - .then( - new Operation() { - @Override - public void apply(RefactoringPreview changes) throws OperationException { - view.setTreeOfChanges(changes); - } - }); - view.showDialog(); } @@ -108,94 +83,227 @@ public void setTitle(String title) { /** {@inheritDoc} */ @Override public void onCancelButtonClicked() { - EditorPartPresenter activeEditor = editorAgent.getActiveEditor(); - if (activeEditor instanceof TextEditor) { - ((TextEditor) activeEditor).setFocus(); - } + view.close(); } /** {@inheritDoc} */ @Override public void onAcceptButtonClicked() { - clientServerEventService - .sendFileTrackingSuspendEvent() - .then( - success -> { - applyRefactoring(); - }); - } + updateFinalEdits(); - private void applyRefactoring() { - refactoringService - .applyRefactoring(session) - .then( - refactoringResult -> { - List changes = refactoringResult.getChanges(); - if (refactoringResult.getSeverity() == OK) { - view.close(); - refactoringUpdater - .updateAfterRefactoring(changes) - .then( - refactoringUpdater - .handleMovingFiles(changes) - .then(clientServerEventService.sendFileTrackingResumeEvent())); - } else { - view.showErrorMessage(refactoringResult); - refactoringUpdater - .handleMovingFiles(changes) - .then(clientServerEventService.sendFileTrackingResumeEvent()); - } - }); + applyWorkspaceEditAction.applyWorkspaceEdit(workspaceEdit); + view.close(); + refactoringActionDelegate.closeWizard(); } /** {@inheritDoc} */ @Override public void onBackButtonClicked() { - if (refactorInfo == null || refactorInfo.getMoveType() == null) { - RenamePresenter renamePresenter = renamePresenterProvider.get(); - renamePresenter.show(refactorInfo); - } else { - MovePresenter movePresenter = movePresenterProvider.get(); - movePresenter.show(refactorInfo); - } - view.close(); } - /** {@inheritDoc} */ @Override - public void onEnabledStateChanged(final RefactoringPreview change) { - ChangeEnabledState changeEnableState = dtoFactory.createDto(ChangeEnabledState.class); - changeEnableState.setChangeId(change.getId()); - changeEnableState.setSessionId(session.getSessionId()); - changeEnableState.setEnabled(change.isEnabled()); - - refactoringService - .changeChangeEnabledState(changeEnableState) - .then( - new Operation() { - @Override - public void apply(Void arg) throws OperationException { - onSelectionChanged(change); - } - }); + public void onSelectionChanged(PreviewNode selectedNode) { + Either data = selectedNode.getData(); + if (data != null && data.isLeft()) { + view.showDiff(null); + return; + } + + List edits = collectTextEditsForSelectedNode(selectedNode); + + updateContentInCompareWidget(selectedNode, edits); } - /** {@inheritDoc} */ - @Override - public void onSelectionChanged(RefactoringPreview change) { - RefactoringChange refactoringChanges = dtoFactory.createDto(RefactoringChange.class); - refactoringChanges.setChangeId(change.getId()); - refactoringChanges.setSessionId(session.getSessionId()); - - Promise changePreviewPromise = - refactoringService.getChangePreview(refactoringChanges); - changePreviewPromise.then( - new Operation() { - @Override - public void apply(ChangePreview arg) throws OperationException { - view.showDiff(arg); + private void updateContentInCompareWidget(PreviewNode selectedNode, List edits) { + String path = selectedNode.getUri(); + Container workspaceRoot = appContext.getWorkspaceRoot(); + Promise> file = workspaceRoot.getFile(path); + file.then( + fileOptional -> { + if (!fileOptional.isPresent()) { + return; } + File existingFile = fileOptional.get(); + existingFile + .getContent() + .then( + content -> { + ChangePreview changePreview = dtoFactory.createDto(ChangePreview.class); + changePreview.setFileName(existingFile.getName()); + changePreview.setOldContent(content); + + // apply all related TextEdit to show new content in compare widget + StringBuilder output = new StringBuilder(); + new StringStreamEditor(edits, content, output).transform(); + String result = output.toString(); + + changePreview.setNewContent(result); + + view.showDiff(changePreview); + }); }); } + + /** + * Finds all enabled TextEdit changes which are children of the selected node and collect them to + * the list. + * + * @param selectedNode the node which was selected + * @return list of the enabled changes + */ + private List collectTextEditsForSelectedNode(PreviewNode selectedNode) { + Either data = selectedNode.getData(); + PreviewNode node = fileNodes.get(selectedNode.getUri()); + List edits = new ArrayList<>(); + if (node.getId().equals(selectedNode.getId())) { + for (PreviewNode child : node.getChildren()) { + TextEdit right = child.getData().getRight(); + if (child.isEnable()) { + edits.add(right); + } + } + } else if (data != null && selectedNode.isEnable()) { + edits.add(data.getRight()); + } + return edits; + } + + @Override + public void onEnabledStateChanged(PreviewNode change) { + Either data = change.getData(); + if (data != null && data.isLeft()) { + ResourceChange left = data.getLeft(); + fileNodes.get(left.getNewUri()).setEnable(change.isEnable()); + } else { + PreviewNode previewNode = fileNodes.get(change.getUri()); + if (previewNode.getId().equals(change.getId())) { + previewNode.setEnable(change.isEnable()); + for (PreviewNode node : previewNode.getChildren()) { + node.setEnable(change.isEnable()); + } + } else { + for (PreviewNode node : previewNode.getChildren()) { + if (node.getId().equals(change.getId())) { + node.setEnable(change.isEnable()); + } + } + } + } + } + + public void show( + CheWorkspaceEdit workspaceEdit, RefactoringActionDelegate refactoringActionDelegate) { + this.workspaceEdit = workspaceEdit; + this.refactoringActionDelegate = refactoringActionDelegate; + + prepareNodes(workspaceEdit); + + view.setTreeOfChanges(fileNodes); + view.showDialog(); + } + + private void prepareNodes(CheWorkspaceEdit workspaceEdit) { + fileNodes.clear(); + prepareTextEditNodes(workspaceEdit.getChanges()); + prepareResourceChangeNodes(workspaceEdit.getCheResourceChanges()); + } + + private void prepareResourceChangeNodes(List resourceChanges) { + for (ResourceChange resourceChange : resourceChanges) { + PreviewNode node = new PreviewNode(); + node.setData(Either.forLeft(resourceChange)); + node.setEnable(true); + String uniqueId = Document.get().createUniqueId(); + node.setId(uniqueId); + String current = resourceChange.getCurrent(); + String newUri = resourceChange.getNewUri(); + node.setUri(newUri); + if (current != null && newUri != null) { + if (Path.valueOf(current) + .removeLastSegments(1) + .equals(Path.valueOf(newUri).removeLastSegments(1))) { + node.setDescription( + "Rename resource '" + + Path.valueOf(current).lastSegment() + + "' to '" + + Path.valueOf(newUri).lastSegment() + + "'"); + } else { + node.setDescription( + "Move resource '" + + Path.valueOf(current).lastSegment() + + "' to '" + + Path.valueOf(newUri).removeLastSegments(1) + + "'"); + } + fileNodes.put(newUri, node); + } else if (current == null && newUri != null) { + node.setDescription("Create resource: '" + Path.valueOf(newUri) + "'"); + fileNodes.put(newUri, node); + } + } + } + + private void prepareTextEditNodes(Map> changes) { + for (String uri : changes.keySet()) { + PreviewNode parent = new PreviewNode(); + parent.setUri(uri); + parent.setEnable(true); + String uniqueId = Document.get().createUniqueId(); + parent.setId(uniqueId); + Path path = Path.valueOf(uri); + parent.setDescription(path.lastSegment() + " - " + path.removeLastSegments(1)); + fileNodes.put(uri, parent); + for (TextEdit change : changes.get(uri)) { + PreviewNode child = new PreviewNode(); + child.setEnable(true); + child.setId(Document.get().createUniqueId()); + child.setDescription("Textual change"); + child.setData(Either.forRight(change)); + child.setUri(uri); + parent.getChildren().add(child); + } + } + } + + private void updateFinalEdits() { + for (PreviewNode node : fileNodes.values()) { + Either data = node.getData(); + if (data != null && data.isLeft()) { + if (node.isEnable()) { + continue; + } + ResourceChange left = data.getLeft(); + List selectedResourceChanges = + workspaceEdit + .getCheResourceChanges() + .stream() + .filter(item -> !item.equals(left)) + .collect(toList()); + workspaceEdit.setCheResourceChanges(selectedResourceChanges); + } else { + if (data == null && !node.isEnable()) { + workspaceEdit.getChanges().remove(node.getUri()); + continue; + } + List children = node.getChildren(); + for (PreviewNode textNode : children) { + if (textNode.isEnable()) { + continue; + } + TextEdit right = textNode.getData().getRight(); + List textNodes = + workspaceEdit + .getChanges() + .get(node.getUri()) + .stream() + .filter(item -> !item.equals(right)) + .collect(toList()); + + workspaceEdit.getChanges().put(node.getUri(), textNodes); + } + } + } + } } diff --git a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/preview/PreviewView.java b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/preview/PreviewView.java index 468406a826d1..4beb95de3c1d 100644 --- a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/preview/PreviewView.java +++ b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/preview/PreviewView.java @@ -11,10 +11,10 @@ package org.eclipse.che.ide.ext.java.client.refactoring.preview; import com.google.inject.ImplementedBy; +import java.util.Map; import org.eclipse.che.commons.annotation.Nullable; import org.eclipse.che.ide.api.mvp.View; import org.eclipse.che.ide.ext.java.shared.dto.refactoring.ChangePreview; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringPreview; import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus; /** @@ -26,13 +26,6 @@ */ @ImplementedBy(PreviewViewImpl.class) interface PreviewView extends View { - /** - * Sets tree of the changes. - * - * @param changes list of changes from the refactoring operation - */ - void setTreeOfChanges(RefactoringPreview changes); - /** * Set a title of the window. * @@ -60,6 +53,13 @@ interface PreviewView extends View { /** Show Preview panel with the special information. */ void showDialog(); + /** + * Sets tree of the changes. + * + * @param nodes changes from the refactoring operation + */ + void setTreeOfChanges(Map nodes); + interface ActionDelegate { /** Performs some actions in response to user's clicking on the 'Cancel' button. */ void onCancelButtonClicked(); @@ -71,9 +71,9 @@ interface ActionDelegate { void onBackButtonClicked(); /** Performs some actions in response to user's choosing some change. */ - void onEnabledStateChanged(RefactoringPreview change); + void onEnabledStateChanged(PreviewNode change); - /** Performs some actions in response to user's selecting some change. */ - void onSelectionChanged(RefactoringPreview change); + /** Performs some actions in response to user selected some change. */ + void onSelectionChanged(PreviewNode selectedNode); } } diff --git a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/preview/PreviewViewImpl.java b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/preview/PreviewViewImpl.java index 025a2813bc60..3fe489947b84 100644 --- a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/preview/PreviewViewImpl.java +++ b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/preview/PreviewViewImpl.java @@ -41,7 +41,6 @@ import org.eclipse.che.ide.api.theme.Style; import org.eclipse.che.ide.ext.java.client.JavaLocalizationConstant; import org.eclipse.che.ide.ext.java.shared.dto.refactoring.ChangePreview; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringPreview; import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus; import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatusEntry; import org.eclipse.che.ide.orion.compare.CompareConfig; @@ -82,7 +81,7 @@ interface PreviewViewImplUiBinder extends UiBinder {} private final CompareInitializer compareInitializer; private final ModuleHolder moduleHolder; - private Map containerChanges = new HashMap<>(); + private Map containerChanges = new HashMap<>(); private Element selectedElement; @Inject @@ -144,8 +143,6 @@ protected void onShow() { errorLabel.setText(""); diff.clear(); compare = null; - treePanel.clear(); - containerChanges.clear(); } @Override @@ -154,20 +151,15 @@ public void setTitleCaption(String title) { } @Override - protected void onHide() { - delegate.onCancelButtonClicked(); - } - - /** {@inheritDoc} */ - @Override - public void setTreeOfChanges(final RefactoringPreview changes) { + public void setTreeOfChanges(Map nodes) { + containerChanges.clear(); showDiffPanel(false); - final SelectionModel selectionModel = new SingleSelectionModel<>(); + final SelectionModel selectionModel = new SingleSelectionModel<>(); selectionModel.addSelectionChangeHandler( event -> { - RefactoringPreview selectedNode = - (RefactoringPreview) ((SingleSelectionModel) selectionModel).getSelectedObject(); + PreviewNode selectedNode = + (PreviewNode) ((SingleSelectionModel) selectionModel).getSelectedObject(); delegate.onSelectionChanged(selectedNode); }); @@ -175,10 +167,10 @@ public void setTreeOfChanges(final RefactoringPreview changes) { tree.getElement().setId("tree-of-changes"); - for (RefactoringPreview parentChange : changes.getChildrens()) { + for (PreviewNode parentChange : nodes.values()) { TreeItem treeItem = new TreeItem(); containerChanges.put(treeItem, parentChange); - createTreeElement(treeItem, parentChange.getText(), parentChange.getChildrens()); + createTreeElement(treeItem, parentChange.getDescription(), parentChange.getChildren()); tree.addItem(treeItem); } @@ -192,11 +184,12 @@ public void setTreeOfChanges(final RefactoringPreview changes) { selectedElement.getStyle().setProperty("background", getEditorSelectionColor()); }); + treePanel.clear(); treePanel.add(tree); } private void createTreeElement( - final TreeItem root, String changeName, List children) { + final TreeItem root, String changeName, List children) { FlowPanel element = new FlowPanel(); element.getElement().getStyle().setFloat(LEFT); CheckBox itemCheckBox = new CheckBox(); @@ -222,8 +215,8 @@ private void createTreeElement( checkChildrenState(root, event.getValue()); checkParentState(root, event.getValue()); - RefactoringPreview change = containerChanges.get(root); - change.setEnabled(event.getValue()); + PreviewNode change = containerChanges.get(root); + change.setEnable(event.getValue()); delegate.onEnabledStateChanged(change); }); @@ -232,10 +225,10 @@ private void createTreeElement( return; } - for (RefactoringPreview child : children) { + for (PreviewNode child : children) { TreeItem treeItem = new TreeItem(); containerChanges.put(treeItem, child); - createTreeElement(treeItem, child.getText(), child.getChildrens()); + createTreeElement(treeItem, child.getDescription(), child.getChildren()); root.addItem(treeItem); } } @@ -317,12 +310,10 @@ public void showDiff(@Nullable ChangePreview preview) { private void refreshComperingFiles(@NotNull ChangePreview preview) { newFile.setContent(preview.getNewContent()); - newFile.setName(preview.getFileName()); oldFile.setContent(preview.getOldContent()); - oldFile.setName(preview.getFileName()); if (compare != null) { - compare.update(newFile, oldFile); + compare.update(oldFile, newFile); } } @@ -333,11 +324,14 @@ private void prepareDiffEditor(@NotNull ChangePreview preview) { oldFile = compareFactory.createFieOptions(); oldFile.setReadOnly(true); + newFile.setName("Refactored Source"); + oldFile.setName("Original Source"); + refreshComperingFiles(preview); CompareConfig compareConfig = compareFactory.createCompareConfig(); - compareConfig.setNewFile(newFile); - compareConfig.setOldFile(oldFile); + compareConfig.setNewFile(oldFile); + compareConfig.setOldFile(newFile); compareConfig.setShowTitle(true); compareConfig.setShowLineStatus(true); diff --git a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/preview/StringStreamEditor.java b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/preview/StringStreamEditor.java new file mode 100644 index 000000000000..5a83d78f4d0e --- /dev/null +++ b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/preview/StringStreamEditor.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2012-2018 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.ide.ext.java.client.refactoring.preview; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Supplier; +import org.eclipse.che.api.languageserver.shared.util.RangeComparator; +import org.eclipse.lsp4j.Position; +import org.eclipse.lsp4j.Range; +import org.eclipse.lsp4j.TextEdit; + +public class StringStreamEditor { + private static final Comparator COMPARATOR = + RangeComparator.transform(new RangeComparator(), TextEdit::getRange); + private ArrayList edits; + private int currentReadLine; + private int currentReadChar; + + private int currentWriteLine; + private int currentWriteChar; + + private int ch; + private Supplier source; + private Consumer sink; + + public StringStreamEditor(Collection edits, String content, StringBuilder output) { + this.edits = new ArrayList<>(edits); + this.edits.sort(COMPARATOR); + this.source = forString(content); + this.sink = ch -> writeAndCount(ch, forStringBuilder(output)); + } + + public List transform() { + List inverse = new ArrayList<>(); + + Iterator editIterator = edits.iterator(); + ch = source.get(); + while (editIterator.hasNext()) { + TextEdit edit = editIterator.next(); + + advanceTo(edit.getRange().getStart(), sink); + Position undoStart = new Position(currentWriteLine, currentWriteChar); + for (int i = 0; i < edit.getNewText().length(); i++) { + sink.accept((int) edit.getNewText().charAt(i)); + } + StringBuilder replaced = new StringBuilder(); + advanceTo(edit.getRange().getEnd(), forStringBuilder(replaced)); + Position undoEnd = new Position(currentWriteLine, currentWriteChar); + inverse.add(new TextEdit(new Range(undoStart, undoEnd), replaced.toString())); + } + // all edits have been processed. Copy the rest of the chars. + while (ch >= 0) { + sink.accept(ch); + ch = source.get(); + } + return inverse; + } + + private void writeAndCount(int ch, Consumer dest) { + dest.accept(ch); + if (ch == '\r') { + // we recognize \r\n, \n + } else if (ch == '\n') { + currentWriteLine++; + currentWriteChar = 0; + } else { + currentWriteChar++; + } + } + + private void advanceTo(Position start, Consumer dest) { + while (ch >= 0 + && (currentReadLine < start.getLine() || currentReadChar < start.getCharacter())) { + dest.accept(ch); + if (ch == '\r') { + currentReadLine++; + currentReadChar = 0; + ch = source.get(); + if (ch == '\n') { + dest.accept(ch); + ch = source.get(); + } + } else if (ch == '\n') { + currentReadLine++; + currentReadChar = 0; + ch = source.get(); + } else { + currentReadChar++; + ch = source.get(); + } + } + } + + public static Consumer forStringBuilder(StringBuilder b) { + return ch -> b.append((char) ch.intValue()); + } + + public static Supplier forString(String text) { + return new Supplier() { + int index = 0; + + @Override + public Integer get() { + return (index >= text.length() ? -1 : text.charAt(index++)); + } + }; + } +} diff --git a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/JavaRefactoringRename.java b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/JavaRefactoringRename.java index 7c33971b14c3..78018368959d 100644 --- a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/JavaRefactoringRename.java +++ b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/JavaRefactoringRename.java @@ -13,24 +13,12 @@ import static org.eclipse.che.ide.api.editor.events.FileEvent.FileOperation.CLOSE; import static org.eclipse.che.ide.api.notification.StatusNotification.DisplayMode.FLOAT_MODE; import static org.eclipse.che.ide.api.notification.StatusNotification.Status.FAIL; -import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.CreateRenameRefactoring.RenameType.JAVA_ELEMENT; -import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus.ERROR; -import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus.FATAL; -import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus.INFO; -import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus.OK; -import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus.WARNING; - -import com.google.common.base.Optional; + import com.google.inject.Inject; import com.google.inject.Singleton; import com.google.web.bindery.event.shared.EventBus; import java.util.ArrayList; import java.util.List; -import javax.validation.constraints.NotNull; -import org.eclipse.che.api.promises.client.Operation; -import org.eclipse.che.api.promises.client.OperationException; -import org.eclipse.che.api.promises.client.Promise; -import org.eclipse.che.api.promises.client.PromiseError; import org.eclipse.che.ide.api.editor.EditorWithAutoSave; import org.eclipse.che.ide.api.editor.document.Document; import org.eclipse.che.ide.api.editor.events.FileEvent; @@ -41,29 +29,29 @@ import org.eclipse.che.ide.api.editor.link.LinkedModelData; import org.eclipse.che.ide.api.editor.link.LinkedModelGroup; import org.eclipse.che.ide.api.editor.text.Position; +import org.eclipse.che.ide.api.editor.text.TextPosition; import org.eclipse.che.ide.api.editor.texteditor.TextEditor; import org.eclipse.che.ide.api.editor.texteditor.UndoableEditor; import org.eclipse.che.ide.api.filewatcher.ClientServerEventService; import org.eclipse.che.ide.api.notification.NotificationManager; -import org.eclipse.che.ide.api.resources.Project; -import org.eclipse.che.ide.api.resources.Resource; import org.eclipse.che.ide.api.resources.VirtualFile; import org.eclipse.che.ide.dto.DtoFactory; import org.eclipse.che.ide.ext.java.client.JavaLocalizationConstant; -import org.eclipse.che.ide.ext.java.client.refactoring.RefactoringUpdater; +import org.eclipse.che.ide.ext.java.client.refactoring.RefactorInfo; +import org.eclipse.che.ide.ext.java.client.refactoring.move.RefactoredItemType; import org.eclipse.che.ide.ext.java.client.refactoring.rename.wizard.RenamePresenter; -import org.eclipse.che.ide.ext.java.client.refactoring.service.RefactoringServiceClient; -import org.eclipse.che.ide.ext.java.client.util.JavaUtil; -import org.eclipse.che.ide.ext.java.shared.dto.LinkedData; -import org.eclipse.che.ide.ext.java.shared.dto.LinkedModeModel; -import org.eclipse.che.ide.ext.java.shared.dto.LinkedPositionGroup; -import org.eclipse.che.ide.ext.java.shared.dto.Region; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.ChangeInfo; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.CreateRenameRefactoring; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.LinkedRenameRefactoringApply; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringResult; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RenameRefactoringSession; +import org.eclipse.che.ide.ext.java.client.service.JavaLanguageExtensionServiceClient; import org.eclipse.che.ide.ui.dialogs.DialogFactory; +import org.eclipse.che.jdt.ls.extension.api.RenameKind; +import org.eclipse.che.jdt.ls.extension.api.dto.RenameSettings; +import org.eclipse.che.plugin.languageserver.ide.editor.quickassist.ApplyWorkspaceEditAction; +import org.eclipse.che.plugin.languageserver.ide.service.TextDocumentServiceClient; +import org.eclipse.che.plugin.languageserver.ide.util.DtoBuildHelper; +import org.eclipse.lsp4j.DidCloseTextDocumentParams; +import org.eclipse.lsp4j.Range; +import org.eclipse.lsp4j.RenameParams; +import org.eclipse.lsp4j.TextDocumentIdentifier; +import org.eclipse.lsp4j.TextDocumentPositionParams; /** * Class for rename refactoring java classes @@ -74,11 +62,15 @@ @Singleton public class JavaRefactoringRename implements FileEventHandler { private final RenamePresenter renamePresenter; - private final RefactoringUpdater refactoringUpdater; + private final DtoBuildHelper dtoHelper; + private final ApplyWorkspaceEditAction applyWorkspaceEditAction; + private final DtoBuildHelper dtoBuildHelper; + private final TextDocumentServiceClient textDocumentServiceClient; private final JavaLocalizationConstant locale; - private final RefactoringServiceClient refactoringServiceClient; private final DtoFactory dtoFactory; + private final JavaLanguageExtensionServiceClient extensionServiceClient; private final ClientServerEventService clientServerEventService; + private final EventBus eventBus; private final DialogFactory dialogFactory; private final NotificationManager notificationManager; @@ -87,24 +79,32 @@ public class JavaRefactoringRename implements FileEventHandler { private LinkedMode mode; private HasLinkedMode linkedEditor; private String newName; + private TextPosition cursorPosition; @Inject public JavaRefactoringRename( RenamePresenter renamePresenter, - RefactoringUpdater refactoringUpdater, + DtoBuildHelper dtoHelper, + ApplyWorkspaceEditAction applyWorkspaceEditAction, + DtoBuildHelper dtoBuildHelper, + TextDocumentServiceClient textDocumentServiceClient, JavaLocalizationConstant locale, - RefactoringServiceClient refactoringServiceClient, + JavaLanguageExtensionServiceClient extensionServiceClient, ClientServerEventService clientServerEventService, DtoFactory dtoFactory, EventBus eventBus, DialogFactory dialogFactory, NotificationManager notificationManager) { this.renamePresenter = renamePresenter; - this.refactoringUpdater = refactoringUpdater; + this.dtoHelper = dtoHelper; + this.applyWorkspaceEditAction = applyWorkspaceEditAction; + this.dtoBuildHelper = dtoBuildHelper; + this.textDocumentServiceClient = textDocumentServiceClient; this.locale = locale; + this.extensionServiceClient = extensionServiceClient; this.clientServerEventService = clientServerEventService; + this.eventBus = eventBus; this.dialogFactory = dialogFactory; - this.refactoringServiceClient = refactoringServiceClient; this.dtoFactory = dtoFactory; this.notificationManager = notificationManager; @@ -124,45 +124,21 @@ public void refactor(final TextEditor textEditorPresenter) { } if (isActiveLinkedEditor) { - createRenameSession(); + if (mode != null) { + mode.exitLinkedMode(false); + } + renamePresenter.show(RefactorInfo.of(RefactoredItemType.JAVA_ELEMENT, null)); + isActiveLinkedEditor = false; } else { + isActiveLinkedEditor = true; textEditor = textEditorPresenter; - - createLinkedRenameSession(); + createLinkedRename(); } - isActiveLinkedEditor = !isActiveLinkedEditor; - linkedEditor = (HasLinkedMode) textEditorPresenter; textEditorPresenter.setFocus(); } - private void createRenameSession() { - final CreateRenameRefactoring refactoringSession = - createRenameRefactoringDto(textEditor, false); - - Promise createRenamePromise = - refactoringServiceClient.createRenameRefactoring(refactoringSession); - createRenamePromise - .then( - new Operation() { - @Override - public void apply(RenameRefactoringSession session) throws OperationException { - renamePresenter.show(session); - if (mode != null) { - mode.exitLinkedMode(false); - } - } - }) - .catchError( - new Operation() { - @Override - public void apply(PromiseError arg) throws OperationException { - showError(); - } - }); - } - private void showError() { dialogFactory .createMessageDialog(locale.renameRename(), locale.renameOperationUnavailable(), null) @@ -172,31 +148,34 @@ private void showError() { } } - private void createLinkedRenameSession() { - final CreateRenameRefactoring refactoringSession = createRenameRefactoringDto(textEditor, true); + private void createLinkedRename() { + cursorPosition = textEditor.getCursorPosition(); - Promise createRenamePromise = - refactoringServiceClient.createRenameRefactoring(refactoringSession); - createRenamePromise + Document document = textEditor.getDocument(); + TextDocumentPositionParams params = + dtoBuildHelper.createTDPP(document, textEditor.getCursorOffset()); + + extensionServiceClient + .getLinkedModeModel(params) .then( - new Operation() { - @Override - public void apply(RenameRefactoringSession session) throws OperationException { - clientServerEventService - .sendFileTrackingSuspendEvent() - .then( - success -> { - activateLinkedModeIntoEditor(session, textEditor.getDocument()); - }); - } + ranges -> { + clientServerEventService + .sendFileTrackingSuspendEvent() + .then( + success -> { + if (ranges == null || ranges.isEmpty()) { + showError(); + isActiveLinkedEditor = false; + clientServerEventService.sendFileTrackingResumeEvent(); + return; + } + activateLinkedModeIntoEditor(ranges); + }); }) .catchError( - new Operation() { - @Override - public void apply(PromiseError arg) throws OperationException { - isActiveLinkedEditor = false; - showError(); - } + arg -> { + isActiveLinkedEditor = false; + showError(); }); } @@ -215,28 +194,21 @@ public boolean isActiveLinkedEditor() { return isActiveLinkedEditor; } - private void activateLinkedModeIntoEditor( - final RenameRefactoringSession session, final Document document) { + private void activateLinkedModeIntoEditor(List ranges) { + sendCloseEvent(); mode = linkedEditor.getLinkedMode(); LinkedModel model = linkedEditor.createLinkedModel(); - LinkedModeModel linkedModeModel = session.getLinkedModeModel(); List groups = new ArrayList<>(); - for (LinkedPositionGroup positionGroup : linkedModeModel.getGroups()) { - LinkedModelGroup group = linkedEditor.createLinkedGroup(); - LinkedData data = positionGroup.getData(); - if (data != null) { - LinkedModelData modelData = linkedEditor.createLinkedModelData(); - modelData.setType("link"); - modelData.setValues(data.getValues()); - group.setData(modelData); - } - List positions = new ArrayList<>(); - for (Region region : positionGroup.getPositions()) { - positions.add(new Position(region.getOffset(), region.getLength())); - } - group.setPositions(positions); - groups.add(group); + LinkedModelGroup group = linkedEditor.createLinkedGroup(); + List positions = new ArrayList<>(); + for (Range range : ranges) { + LinkedModelData modelData = linkedEditor.createLinkedModelData(); + modelData.setType("link"); + group.setData(modelData); + positions.add(createPositionFromRange(range, textEditor.getDocument())); } + group.setPositions(positions); + groups.add(group); model.setGroups(groups); disableAutoSave(); @@ -250,15 +222,16 @@ public void onLinkedModeExited(boolean successful, int start, int end) { try { if (successful) { isSuccessful = true; - newName = document.getContentRange(start, end - start); - performRename(session); + newName = textEditor.getDocument().getContentRange(start, end - start); + performRename(newName); } } finally { mode.removeListener(this); + isActiveLinkedEditor = false; boolean isNameChanged = start >= 0 && end >= 0; - if (!isSuccessful && isNameChanged) { + if (!isSuccessful && isNameChanged && textEditor.isDirty()) { undoChanges(); } @@ -275,81 +248,79 @@ public void onLinkedModeExited(boolean successful, int start, int end) { }); } - private void performRename(RenameRefactoringSession session) { - final LinkedRenameRefactoringApply dto = - createLinkedRenameRefactoringApplyDto(newName, session.getSessionId()); - Promise applyModelPromise = - refactoringServiceClient.applyLinkedModeRename(dto); - applyModelPromise + private Position createPositionFromRange(Range range, Document document) { + int start = + document.getIndexFromPosition( + new TextPosition(range.getStart().getLine(), range.getStart().getCharacter())); + int end = + document.getIndexFromPosition( + new TextPosition(range.getEnd().getLine(), range.getEnd().getCharacter())); + + if (start == -1 && end == -1) { + return new Position(0); + } + + if (start == -1) { + return new Position(end); + } + + if (end == -1) { + return new Position(start); + } + + int length = end - start; + if (length < 0) { + return null; + } + return new Position(start, length); + } + + private void sendCloseEvent() { + TextDocumentIdentifier documentId = dtoHelper.createTDI(textEditor.getEditorInput().getFile()); + DidCloseTextDocumentParams closeEvent = dtoFactory.createDto(DidCloseTextDocumentParams.class); + closeEvent.setTextDocument(documentId); + textDocumentServiceClient.didClose(closeEvent); + } + + private void sendOpenEvent() { + eventBus.fireEvent(FileEvent.createFileOpenedEvent(textEditor.getEditorInput().getFile())); + } + + private void performRename(String newName) { + RenameSettings settings = dtoFactory.createDto(RenameSettings.class); + + RenameParams renameParams = dtoFactory.createDto(RenameParams.class); + renameParams.setNewName(newName); + VirtualFile file = textEditor.getEditorInput().getFile(); + TextDocumentIdentifier textDocumentIdentifier = dtoBuildHelper.createTDI(file); + renameParams.setTextDocument(textDocumentIdentifier); + + org.eclipse.lsp4j.Position position = dtoFactory.createDto(org.eclipse.lsp4j.Position.class); + position.setCharacter(cursorPosition.getCharacter()); + position.setLine(cursorPosition.getLine()); + renameParams.setPosition(position); + + settings.setUpdateReferences(true); + settings.setRenameParams(renameParams); + settings.setRenameKind(RenameKind.JAVA_ELEMENT); + + extensionServiceClient + .rename(settings) .then( - new Operation() { - @Override - public void apply(RefactoringResult result) throws OperationException { - switch (result.getSeverity()) { - case OK: - case INFO: - List changes = result.getChanges(); - refactoringUpdater - .updateAfterRefactoring(changes) - .then( - arg -> { - final VirtualFile file = textEditor.getDocument().getFile(); - - if (file instanceof Resource) { - final Optional project = - ((Resource) file).getRelatedProject(); - - refactoringServiceClient.reindexProject( - project.get().getLocation().toString()); - } - - enableAutoSave(); - refactoringUpdater - .handleMovingFiles(changes) - .then(clientServerEventService.sendFileTrackingResumeEvent()); - }); - - break; - case WARNING: - case ERROR: - enableAutoSave(); - - undoChanges(); - - showWarningDialog(); - break; - case FATAL: - undoChanges(); - - clientServerEventService.sendFileTrackingResumeEvent(); - - notificationManager.notify( - locale.failedToRename(), - result.getEntries().get(0).getMessage(), - FAIL, - FLOAT_MODE); - break; - default: - break; - } - } + edits -> { + enableAutoSave(); + undoChanges(); + applyWorkspaceEditAction.applyWorkspaceEdit(edits); + clientServerEventService.sendFileTrackingResumeEvent(); + sendOpenEvent(); }) .catchError( - new Operation() { - @Override - public void apply(PromiseError arg) throws OperationException { - undoChanges(); - - clientServerEventService - .sendFileTrackingResumeEvent() - .then( - success -> { - enableAutoSave(); - }); - - notificationManager.notify( - locale.failedToRename(), arg.getMessage(), FAIL, FLOAT_MODE); - } + error -> { + undoChanges(); + enableAutoSave(); + clientServerEventService.sendFileTrackingResumeEvent(); + notificationManager.notify( + locale.failedToRename(), error.getMessage(), FAIL, FLOAT_MODE); }); } @@ -370,54 +341,4 @@ private void undoChanges() { ((UndoableEditor) linkedEditor).getUndoRedo().undo(); } } - - private void showWarningDialog() { - dialogFactory - .createConfirmDialog( - locale.warningOperationTitle(), - locale.renameWithWarnings(), - locale.showRenameWizard(), - locale.buttonCancel(), - () -> { - isActiveLinkedEditor = true; - - refactor(textEditor); - - isActiveLinkedEditor = false; - }, - clientServerEventService::sendFileTrackingResumeEvent) - .show(); - } - - @NotNull - private CreateRenameRefactoring createRenameRefactoringDto( - TextEditor editor, boolean isActiveLinkedMode) { - CreateRenameRefactoring dto = dtoFactory.createDto(CreateRenameRefactoring.class); - - dto.setOffset(editor.getCursorOffset()); - dto.setRefactorLightweight(isActiveLinkedMode); - - final VirtualFile file = editor.getEditorInput().getFile(); - - dto.setPath(JavaUtil.resolveFQN(file)); - - if (file instanceof Resource) { - final Optional project = ((Resource) file).getRelatedProject(); - - dto.setProjectPath(project.get().getLocation().toString()); - } - - dto.setType(JAVA_ELEMENT); - - return dto; - } - - @NotNull - private LinkedRenameRefactoringApply createLinkedRenameRefactoringApplyDto( - String newName, String sessionId) { - LinkedRenameRefactoringApply dto = dtoFactory.createDto(LinkedRenameRefactoringApply.class); - dto.setNewName(newName); - dto.setSessionId(sessionId); - return dto; - } } diff --git a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/RenameRefactoringAction.java b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/RenameRefactoringAction.java index 7f70a4e7d699..a02c1fa9d9f8 100644 --- a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/RenameRefactoringAction.java +++ b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/RenameRefactoringAction.java @@ -11,8 +11,7 @@ package org.eclipse.che.ide.ext.java.client.refactoring.rename; import static org.eclipse.che.ide.api.resources.Resource.FILE; -import static org.eclipse.che.ide.ext.java.client.refactoring.move.RefactoredItemType.COMPILATION_UNIT; -import static org.eclipse.che.ide.ext.java.client.refactoring.move.RefactoredItemType.PACKAGE; +import static org.eclipse.che.ide.ext.java.client.util.JavaUtil.isJavaProject; import com.google.common.base.Optional; import com.google.gwt.user.client.rpc.AsyncCallback; @@ -39,7 +38,6 @@ import org.eclipse.che.ide.ext.java.client.refactoring.move.RefactoredItemType; import org.eclipse.che.ide.ext.java.client.refactoring.rename.wizard.RenamePresenter; import org.eclipse.che.ide.ext.java.client.resource.SourceFolderMarker; -import org.eclipse.che.ide.ext.java.client.util.JavaUtil; import org.eclipse.che.ide.ui.dialogs.DialogFactory; import org.eclipse.che.ide.util.loging.Log; @@ -134,9 +132,9 @@ private void performAction() { final Resource resource = resources[0]; - final Optional project = resource.getRelatedProject(); + final Project project = resource.getProject(); - if (!JavaUtil.isJavaProject(project.get())) { + if (!isJavaProject(project)) { return; } @@ -149,9 +147,9 @@ private void performAction() { RefactoredItemType renamedItemType = null; if (resource.getResourceType() == FILE && isJavaFile((File) resource)) { - renamedItemType = COMPILATION_UNIT; + renamedItemType = RefactoredItemType.COMPILATION_UNIT; } else if (resource instanceof Container) { - renamedItemType = PACKAGE; + renamedItemType = RefactoredItemType.PACKAGE; } if (renamedItemType == null) { @@ -176,16 +174,14 @@ public void updateInPerspective(ActionEvent event) { final VirtualFile file = editorPart.getEditorInput().getFile(); if (file instanceof File) { - final Optional project = ((File) file).getRelatedProject(); + final Project project = ((File) file).getProject(); - if (!project.isPresent()) { + if (project == null) { event.getPresentation().setEnabledAndVisible(false); return; } - event - .getPresentation() - .setEnabledAndVisible(JavaUtil.isJavaProject(project.get()) && isJavaFile(file)); + event.getPresentation().setEnabledAndVisible(isJavaProject(project) && isJavaFile(file)); } else { event.getPresentation().setEnabledAndVisible(isJavaFile(file)); } @@ -200,9 +196,9 @@ public void updateInPerspective(ActionEvent event) { final Resource resource = resources[0]; - final Optional project = resource.getRelatedProject(); + final Project project = resource.getProject(); - if (!project.isPresent()) { + if (project == null) { event.getPresentation().setEnabledAndVisible(false); return; } @@ -213,13 +209,11 @@ public void updateInPerspective(ActionEvent event) { event .getPresentation() .setEnabledAndVisible( - JavaUtil.isJavaProject(project.get()) - && srcFolder.isPresent() - && isJavaFile((File) resource)); + isJavaProject(project) && srcFolder.isPresent() && isJavaFile((File) resource)); } else if (resource instanceof Container) { event .getPresentation() - .setEnabledAndVisible(JavaUtil.isJavaProject(project.get()) && srcFolder.isPresent()); + .setEnabledAndVisible(isJavaProject(project) && srcFolder.isPresent()); } } } @@ -227,11 +221,7 @@ public void updateInPerspective(ActionEvent event) { protected boolean isJavaFile(VirtualFile file) { String fileExtension = fileTypeRegistry.getFileTypeByFile(file).getExtension(); - if (fileExtension == null) { - return false; - } - - return fileExtension.equals("java") || fileExtension.equals("class"); + return fileExtension != null && (fileExtension.equals("java") || fileExtension.equals("class")); } @Override diff --git a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/RenamePresenter.java b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/RenamePresenter.java index d99c91d49ae2..90794e9a9a1b 100644 --- a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/RenamePresenter.java +++ b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/RenamePresenter.java @@ -10,109 +10,81 @@ */ package org.eclipse.che.ide.ext.java.client.refactoring.rename.wizard; -import static com.google.common.base.Preconditions.checkState; import static org.eclipse.che.ide.api.notification.StatusNotification.DisplayMode.FLOAT_MODE; import static org.eclipse.che.ide.api.notification.StatusNotification.Status.FAIL; -import static org.eclipse.che.ide.api.resources.Resource.FILE; -import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.CreateRenameRefactoring.RenameType.COMPILATION_UNIT; -import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.CreateRenameRefactoring.RenameType.JAVA_ELEMENT; -import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.CreateRenameRefactoring.RenameType.PACKAGE; -import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus.ERROR; -import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus.FATAL; -import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus.INFO; -import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus.OK; -import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus.WARNING; import com.google.inject.Inject; import com.google.inject.Singleton; -import java.util.List; -import org.eclipse.che.api.promises.client.Function; -import org.eclipse.che.api.promises.client.FunctionException; -import org.eclipse.che.api.promises.client.Operation; -import org.eclipse.che.api.promises.client.OperationException; import org.eclipse.che.api.promises.client.Promise; -import org.eclipse.che.api.promises.client.PromiseError; -import org.eclipse.che.ide.api.app.AppContext; import org.eclipse.che.ide.api.editor.EditorAgent; import org.eclipse.che.ide.api.editor.EditorPartPresenter; +import org.eclipse.che.ide.api.editor.text.TextPosition; import org.eclipse.che.ide.api.editor.texteditor.TextEditor; -import org.eclipse.che.ide.api.filewatcher.ClientServerEventService; import org.eclipse.che.ide.api.notification.NotificationManager; -import org.eclipse.che.ide.api.resources.Container; -import org.eclipse.che.ide.api.resources.Project; import org.eclipse.che.ide.api.resources.Resource; import org.eclipse.che.ide.api.resources.VirtualFile; import org.eclipse.che.ide.dto.DtoFactory; import org.eclipse.che.ide.ext.java.client.JavaLocalizationConstant; import org.eclipse.che.ide.ext.java.client.refactoring.RefactorInfo; -import org.eclipse.che.ide.ext.java.client.refactoring.RefactoringUpdater; +import org.eclipse.che.ide.ext.java.client.refactoring.RefactoringActionDelegate; +import org.eclipse.che.ide.ext.java.client.refactoring.move.RefactoredItemType; import org.eclipse.che.ide.ext.java.client.refactoring.preview.PreviewPresenter; import org.eclipse.che.ide.ext.java.client.refactoring.rename.wizard.RenameView.ActionDelegate; import org.eclipse.che.ide.ext.java.client.refactoring.rename.wizard.similarnames.SimilarNamesConfigurationPresenter; -import org.eclipse.che.ide.ext.java.client.refactoring.service.RefactoringServiceClient; -import org.eclipse.che.ide.ext.java.client.util.JavaUtil; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.ChangeCreationResult; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.ChangeInfo; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.CreateRenameRefactoring; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringSession; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatusEntry; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RenameRefactoringSession; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RenameSettings; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.ValidateNewName; -import org.eclipse.che.ide.ui.dialogs.DialogFactory; -import org.eclipse.che.ide.ui.dialogs.confirm.ConfirmCallback; +import org.eclipse.che.ide.ext.java.client.service.JavaLanguageExtensionServiceClient; +import org.eclipse.che.jdt.ls.extension.api.RenameKind; +import org.eclipse.che.jdt.ls.extension.api.dto.CheWorkspaceEdit; +import org.eclipse.che.jdt.ls.extension.api.dto.RenameSelectionParams; +import org.eclipse.che.jdt.ls.extension.api.dto.RenameSettings; +import org.eclipse.che.jdt.ls.extension.api.dto.RenamingElementInfo; +import org.eclipse.che.plugin.languageserver.ide.editor.quickassist.ApplyWorkspaceEditAction; +import org.eclipse.che.plugin.languageserver.ide.util.DtoBuildHelper; +import org.eclipse.lsp4j.RenameParams; +import org.eclipse.lsp4j.TextDocumentIdentifier; /** - * The class that manages Move panel widget. + * The class that manages Rename panel widget. * * @author Valeriy Svydenko */ @Singleton -public class RenamePresenter implements ActionDelegate { +public class RenamePresenter implements ActionDelegate, RefactoringActionDelegate { private final RenameView view; + private final JavaLanguageExtensionServiceClient extensionServiceClient; private final SimilarNamesConfigurationPresenter similarNamesConfigurationPresenter; + private final ApplyWorkspaceEditAction applyWorkspaceEditAction; private final JavaLocalizationConstant locale; - private final RefactoringUpdater refactoringUpdater; + private final DtoBuildHelper dtoBuildHelper; private final EditorAgent editorAgent; private final NotificationManager notificationManager; - private final AppContext appContext; private final PreviewPresenter previewPresenter; private final DtoFactory dtoFactory; - private final RefactoringServiceClient refactorService; - private final DialogFactory dialogFactory; - private final ClientServerEventService clientServerEventService; - private RenameRefactoringSession renameRefactoringSession; private RefactorInfo refactorInfo; @Inject public RenamePresenter( RenameView view, + JavaLanguageExtensionServiceClient extensionServiceClient, SimilarNamesConfigurationPresenter similarNamesConfigurationPresenter, + ApplyWorkspaceEditAction applyWorkspaceEditAction, JavaLocalizationConstant locale, + DtoBuildHelper dtoBuildHelper, EditorAgent editorAgent, - RefactoringUpdater refactoringUpdater, - AppContext appContext, NotificationManager notificationManager, PreviewPresenter previewPresenter, - RefactoringServiceClient refactorService, - ClientServerEventService clientServerEventService, - DtoFactory dtoFactory, - DialogFactory dialogFactory) { + DtoFactory dtoFactory) { this.view = view; + this.extensionServiceClient = extensionServiceClient; this.similarNamesConfigurationPresenter = similarNamesConfigurationPresenter; + this.applyWorkspaceEditAction = applyWorkspaceEditAction; this.locale = locale; - this.refactoringUpdater = refactoringUpdater; + this.dtoBuildHelper = dtoBuildHelper; this.editorAgent = editorAgent; this.notificationManager = notificationManager; - this.clientServerEventService = clientServerEventService; this.view.setDelegate(this); - this.appContext = appContext; this.previewPresenter = previewPresenter; - this.refactorService = refactorService; this.dtoFactory = dtoFactory; - this.dialogFactory = dialogFactory; } /** @@ -122,39 +94,45 @@ public RenamePresenter( */ public void show(RefactorInfo refactorInfo) { this.refactorInfo = refactorInfo; - final CreateRenameRefactoring createRenameRefactoring = - createRenameRefactoringDto(refactorInfo); + TextEditor editor = (TextEditor) editorAgent.getActiveEditor(); + + RenameSelectionParams params = dtoFactory.createDto(RenameSelectionParams.class); + + if (RefactoredItemType.JAVA_ELEMENT.equals(refactorInfo.getRefactoredItemType())) { + TextPosition cursorPosition = editor.getCursorPosition(); + org.eclipse.lsp4j.Position position = dtoFactory.createDto(org.eclipse.lsp4j.Position.class); + position.setCharacter(cursorPosition.getCharacter()); + position.setLine(cursorPosition.getLine()); + params.setPosition(position); + String location = + editorAgent.getActiveEditor().getEditorInput().getFile().getLocation().toString(); + params.setResourceUri(location); + params.setRenameKind(RenameKind.JAVA_ELEMENT); + } else { + // get selected resource + Resource resource = refactorInfo.getResources()[0]; + params.setResourceUri(resource.getLocation().toString()); + if (RefactoredItemType.COMPILATION_UNIT.equals(refactorInfo.getRefactoredItemType())) { + params.setRenameKind(RenameKind.COMPILATION_UNIT); + } else { + params.setRenameKind(RenameKind.PACKAGE); + } + } - Promise createRenamePromise = - refactorService.createRenameRefactoring(createRenameRefactoring); - createRenamePromise - .then( - new Operation() { - @Override - public void apply(RenameRefactoringSession session) throws OperationException { - show(session); - } - }) + extensionServiceClient + .getRenameType(params) + .then(this::showWizard) .catchError( - new Operation() { - @Override - public void apply(PromiseError arg) throws OperationException { - notificationManager.notify( - locale.failedToRename(), arg.getMessage(), FAIL, FLOAT_MODE); - } + error -> { + notificationManager.notify( + locale.failedToRename(), error.getMessage(), FAIL, FLOAT_MODE); }); } - /** - * Show Rename window with the special information. - * - * @param renameRefactoringSession data of current refactoring session - */ - public void show(RenameRefactoringSession renameRefactoringSession) { - this.renameRefactoringSession = renameRefactoringSession; - prepareWizard(); + private void showWizard(RenamingElementInfo elementInfo) { + prepareWizard(elementInfo.getElementName()); - switch (renameRefactoringSession.getWizardType()) { + switch (elementInfo.getRenameKind()) { case COMPILATION_UNIT: view.setTitleCaption(locale.renameCompilationUnitTitle()); view.setVisiblePatternsPanel(true); @@ -197,6 +175,18 @@ public void show(RenameRefactoringSession renameRefactoringSession) { view.showDialog(); } + private void prepareWizard(String oldName) { + view.clearErrorLabel(); + view.setOldName(oldName); + view.setVisiblePatternsPanel(false); + view.setVisibleFullQualifiedNamePanel(false); + view.setVisibleKeepOriginalPanel(false); + view.setVisibleRenameSubpackagesPanel(false); + view.setVisibleSimilarlyVariablesPanel(false); + view.setEnableAcceptButton(false); + view.setEnablePreviewButton(false); + } + /** {@inheritDoc} */ @Override public void onPreviewButtonClicked() { @@ -206,7 +196,7 @@ public void onPreviewButtonClicked() { /** {@inheritDoc} */ @Override public void onAcceptButtonClicked() { - applyChanges(); + getChanges().then(this::applyRefactoring); } /** {@inheritDoc} */ @@ -225,214 +215,125 @@ private void setEditorFocus() { /** {@inheritDoc} */ @Override public void validateName() { - ValidateNewName validateNewName = dtoFactory.createDto(ValidateNewName.class); - validateNewName.setSessionId(renameRefactoringSession.getSessionId()); - validateNewName.setNewName(view.getNewName()); - - refactorService - .validateNewName(validateNewName) - .then( - new Operation() { - @Override - public void apply(RefactoringStatus arg) throws OperationException { - switch (arg.getSeverity()) { - case OK: - view.setEnableAcceptButton(true); - view.setEnablePreviewButton(true); - view.clearErrorLabel(); - break; - case INFO: - view.setEnableAcceptButton(true); - view.setEnablePreviewButton(true); - view.showStatusMessage(arg); - break; - default: - view.setEnableAcceptButton(false); - view.setEnablePreviewButton(false); - view.showErrorMessage(arg); - break; - } - } - }) - .catchError( - new Operation() { - @Override - public void apply(PromiseError arg) throws OperationException { - notificationManager.notify( - locale.failedToRename(), arg.getMessage(), FAIL, FLOAT_MODE); - } - }); - } - - private void prepareWizard() { - view.clearErrorLabel(); - view.setOldName(renameRefactoringSession.getOldName()); - view.setVisiblePatternsPanel(false); - view.setVisibleFullQualifiedNamePanel(false); - view.setVisibleKeepOriginalPanel(false); - view.setVisibleRenameSubpackagesPanel(false); - view.setVisibleSimilarlyVariablesPanel(false); - view.setEnableAcceptButton(false); - view.setEnablePreviewButton(false); - } + RenameSelectionParams params = dtoFactory.createDto(RenameSelectionParams.class); + + if (RefactoredItemType.JAVA_ELEMENT.equals(refactorInfo.getRefactoredItemType())) { + TextEditor editor = (TextEditor) editorAgent.getActiveEditor(); + TextPosition cursorPosition = editor.getCursorPosition(); + org.eclipse.lsp4j.Position position = dtoFactory.createDto(org.eclipse.lsp4j.Position.class); + position.setCharacter(cursorPosition.getCharacter()); + position.setLine(cursorPosition.getLine()); + params.setPosition(position); + params.setRenameKind(RenameKind.JAVA_ELEMENT); + String location = + editorAgent.getActiveEditor().getEditorInput().getFile().getLocation().toString(); + params.setResourceUri(location); + } else if (RefactoredItemType.COMPILATION_UNIT.equals(refactorInfo.getRefactoredItemType())) { + params.setRenameKind(RenameKind.COMPILATION_UNIT); + params.setResourceUri(refactorInfo.getResources()[0].getLocation().toString()); + } else if (RefactoredItemType.PACKAGE.equals(refactorInfo.getRefactoredItemType())) { + params.setRenameKind(RenameKind.PACKAGE); + params.setResourceUri(refactorInfo.getResources()[0].getLocation().toString()); + } - private void showPreview() { - RefactoringSession session = dtoFactory.createDto(RefactoringSession.class); - session.setSessionId(renameRefactoringSession.getSessionId()); + params.setNewName(view.getNewName()); - prepareRenameChanges(session) + extensionServiceClient + .validateRenamedName(params) .then( - new Operation() { - @Override - public void apply(ChangeCreationResult arg) throws OperationException { - if (arg.isCanShowPreviewPage() || arg.getStatus().getSeverity() <= 3) { - previewPresenter.show(renameRefactoringSession.getSessionId(), refactorInfo); - previewPresenter.setTitle(locale.renameItemTitle()); - view.close(); - } else { - view.showErrorMessage(arg.getStatus()); - } + status -> { + if (status == null) { + return; } - }) - .catchError( - new Operation() { - @Override - public void apply(PromiseError arg) throws OperationException { - notificationManager.notify( - locale.failedToRename(), arg.getMessage(), FAIL, FLOAT_MODE); - } - }); - } - - private void applyChanges() { - final RefactoringSession session = dtoFactory.createDto(RefactoringSession.class); - session.setSessionId(renameRefactoringSession.getSessionId()); - - prepareRenameChanges(session) - .then( - new Operation() { - @Override - public void apply(ChangeCreationResult arg) throws OperationException { - int severityCode = arg.getStatus().getSeverity(); - - switch (severityCode) { - case WARNING: - case ERROR: - showWarningDialog(session, arg); - break; - case FATAL: - if (!arg.isCanShowPreviewPage()) { - view.showErrorMessage(arg.getStatus()); - } - break; - default: - clientServerEventService - .sendFileTrackingSuspendEvent() - .then( - success -> { - applyRefactoring(session); - }); - } + switch (status.getRefactoringSeverity()) { + case OK: + view.setEnableAcceptButton(true); + view.setEnablePreviewButton(true); + view.clearErrorLabel(); + break; + case INFO: + view.setEnableAcceptButton(true); + view.setEnablePreviewButton(true); + view.showStatusMessage(status); + break; + default: + view.setEnableAcceptButton(false); + view.setEnablePreviewButton(false); + view.showErrorMessage(status); + break; } }) .catchError( - new Operation() { - @Override - public void apply(PromiseError arg) throws OperationException { - notificationManager.notify( - locale.failedToRename(), arg.getMessage(), FAIL, FLOAT_MODE); - } + error -> { + notificationManager.notify( + locale.failedToRename(), error.getMessage(), FAIL, FLOAT_MODE); }); } - private void showWarningDialog( - final RefactoringSession session, ChangeCreationResult changeCreationResult) { - List entries = changeCreationResult.getStatus().getEntries(); - - ConfirmCallback confirmCallback = - () -> - clientServerEventService - .sendFileTrackingSuspendEvent() - .then( - success -> { - applyRefactoring(session); - }); - - dialogFactory - .createConfirmDialog( - locale.warningOperationTitle(), - entries.isEmpty() ? locale.warningOperationContent() : entries.get(0).getMessage(), - locale.renameRename(), - locale.buttonCancel(), - confirmCallback, - () -> {}) - .show(); - } - - private void applyRefactoring(RefactoringSession session) { - refactorService - .applyRefactoring(session) + private void showPreview() { + getChanges() .then( - refactoringResult -> { - List changes = refactoringResult.getChanges(); - if (refactoringResult.getSeverity() == OK) { - view.close(); - updateAfterRefactoring(changes) - .then( - refactoringUpdater - .handleMovingFiles(changes) - .then(clientServerEventService.sendFileTrackingResumeEvent())); - } else { - view.showErrorMessage(refactoringResult); - refactoringUpdater - .handleMovingFiles(changes) - .then(clientServerEventService.sendFileTrackingResumeEvent()); - } + workspaceEdit -> { + previewPresenter.show(workspaceEdit, this); + previewPresenter.setTitle(locale.renameItemTitle()); }); } - private Promise updateAfterRefactoring(List changes) { - return refactoringUpdater - .updateAfterRefactoring(changes) - .then( - arg -> { - final Resource[] resources = - refactorInfo != null ? refactorInfo.getResources() : null; - Project project = null; - - final Resource resource = - (resources != null && resources.length == 1) - ? resources[0] - : appContext.getResource(); - if (resource != null) { - project = resource.getProject(); - } + private Promise getChanges() { + RenameSettings renameSettings = createRenameSettings(); + RenameParams renameParams = createRenameParams(renameSettings); - if (project != null) { - refactorService.reindexProject(project.getLocation().toString()); - } + renameSettings.setRenameParams(renameParams); - setEditorFocus(); + return extensionServiceClient + .rename(renameSettings) + .catchError( + arg -> { + notificationManager.notify( + locale.failedToRename(), arg.getMessage(), FAIL, FLOAT_MODE); }); } - private Promise prepareRenameChanges(final RefactoringSession session) { - RenameSettings renameSettings = createRenameSettingsDto(session); + private RenameParams createRenameParams(RenameSettings renameSettings) { + RenameParams renameParams = dtoFactory.createDto(RenameParams.class); + renameParams.setNewName(view.getNewName()); + + if (RefactoredItemType.JAVA_ELEMENT.equals(refactorInfo.getRefactoredItemType())) { + EditorPartPresenter activeEditor = editorAgent.getActiveEditor(); + VirtualFile file = activeEditor.getEditorInput().getFile(); + TextDocumentIdentifier textDocumentIdentifier = dtoBuildHelper.createTDI(file); + renameParams.setTextDocument(textDocumentIdentifier); + + TextPosition cursorPosition = ((TextEditor) activeEditor).getCursorPosition(); + org.eclipse.lsp4j.Position position = dtoFactory.createDto(org.eclipse.lsp4j.Position.class); + position.setCharacter(cursorPosition.getCharacter()); + position.setLine(cursorPosition.getLine()); + renameParams.setPosition(position); + renameSettings.setRenameKind(RenameKind.JAVA_ELEMENT); + } else if (RefactoredItemType.COMPILATION_UNIT.equals(refactorInfo.getRefactoredItemType())) { + renameSettings.setRenameKind(RenameKind.COMPILATION_UNIT); + TextDocumentIdentifier textDocumentIdentifier = + dtoFactory.createDto(TextDocumentIdentifier.class); + textDocumentIdentifier.setUri(refactorInfo.getResources()[0].getLocation().toString()); + renameParams.setTextDocument(textDocumentIdentifier); + } else if (RefactoredItemType.PACKAGE.equals(refactorInfo.getRefactoredItemType())) { + renameSettings.setRenameKind(RenameKind.PACKAGE); + TextDocumentIdentifier textDocumentIdentifier = + dtoFactory.createDto(TextDocumentIdentifier.class); + textDocumentIdentifier.setUri(refactorInfo.getResources()[0].getLocation().toString()); + renameParams.setTextDocument(textDocumentIdentifier); + } + return renameParams; + } - return refactorService - .setRenameSettings(renameSettings) - .thenPromise( - new Function>() { - @Override - public Promise apply(Void arg) throws FunctionException { - return refactorService.createChange(session); - } - }); + private void applyRefactoring(CheWorkspaceEdit workspaceEdit) { + view.close(); + applyWorkspaceEditAction.applyWorkspaceEdit(workspaceEdit); + setEditorFocus(); } - private RenameSettings createRenameSettingsDto(RefactoringSession session) { + private RenameSettings createRenameSettings() { RenameSettings renameSettings = dtoFactory.createDto(RenameSettings.class); - renameSettings.setSessionId(session.getSessionId()); renameSettings.setDelegateUpdating(view.isUpdateDelegateUpdating()); if (view.isUpdateDelegateUpdating()) { renameSettings.setDeprecateDelegates(view.isUpdateMarkDeprecated()); @@ -446,50 +347,15 @@ private RenameSettings createRenameSettingsDto(RefactoringSession session) { renameSettings.setUpdateTextualMatches(view.isUpdateTextualOccurrences()); renameSettings.setUpdateSimilarDeclarations(view.isUpdateSimilarlyVariables()); if (view.isUpdateSimilarlyVariables()) { - renameSettings.setMachStrategy( - similarNamesConfigurationPresenter.getMachStrategy().getValue()); + renameSettings.setMatchStrategy(similarNamesConfigurationPresenter.getMatchStrategy()); } return renameSettings; } - private CreateRenameRefactoring createRenameRefactoringDto(RefactorInfo refactorInfo) { - CreateRenameRefactoring dto = dtoFactory.createDto(CreateRenameRefactoring.class); - - dto.setRefactorLightweight(false); - - if (refactorInfo == null) { - final VirtualFile file = editorAgent.getActiveEditor().getEditorInput().getFile(); - - dto.setType(JAVA_ELEMENT); - dto.setPath(JavaUtil.resolveFQN(file)); - dto.setOffset(((TextEditor) editorAgent.getActiveEditor()).getCursorOffset()); - - if (file instanceof Resource) { - final Project project = ((Resource) file).getRelatedProject().get(); - - dto.setProjectPath(project.getLocation().toString()); - } - } else { - final Resource[] resources = refactorInfo.getResources(); - - checkState(resources != null && resources.length == 1); - - final Resource resource = resources[0]; - - if (resource.getResourceType() == FILE) { - dto.setPath(JavaUtil.resolveFQN(resource)); - dto.setType(COMPILATION_UNIT); - } else if (resource instanceof Container) { - dto.setPath(resource.getLocation().toString()); - dto.setType(PACKAGE); - } - - final Project project = resource.getRelatedProject().get(); - - dto.setProjectPath(project.getLocation().toString()); - } - - return dto; + @Override + public void closeWizard() { + view.close(); + setEditorFocus(); } } diff --git a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/RenameView.java b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/RenameView.java index 5c1a663362b5..3756dc38566f 100644 --- a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/RenameView.java +++ b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/RenameView.java @@ -12,7 +12,7 @@ import com.google.inject.ImplementedBy; import org.eclipse.che.ide.api.mvp.View; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus; +import org.eclipse.che.jdt.ls.extension.api.dto.NameValidationStatus; /** * The visual part of Rename wizard that has an ability to show configuration of a refactoring @@ -89,14 +89,14 @@ interface RenameView extends View { * * @param status status of move operation */ - void showStatusMessage(RefactoringStatus status); + void showStatusMessage(NameValidationStatus status); /** * Show error message into bottom of view. * * @param status status of error move operation */ - void showErrorMessage(RefactoringStatus status); + void showErrorMessage(NameValidationStatus status); void setFocus(); diff --git a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/RenameViewImpl.java b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/RenameViewImpl.java index 49dd32976ac4..f6ddb4ccb4c1 100644 --- a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/RenameViewImpl.java +++ b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/RenameViewImpl.java @@ -31,9 +31,9 @@ import org.eclipse.che.ide.ext.java.client.JavaLocalizationConstant; import org.eclipse.che.ide.ext.java.client.JavaResources; import org.eclipse.che.ide.ext.java.client.refactoring.rename.wizard.similarnames.SimilarNamesConfigurationPresenter; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatusEntry; import org.eclipse.che.ide.ui.window.Window; +import org.eclipse.che.jdt.ls.extension.api.dto.NameValidationStatus; +import org.eclipse.che.jdt.ls.extension.api.dto.RefactoringStatusEntry; /** @author Valeriy Svydenko */ @Singleton @@ -235,14 +235,14 @@ public void setVisibleSimilarlyVariablesPanel(boolean isVisible) { /** {@inheritDoc} */ @Override - public void showStatusMessage(RefactoringStatus status) { + public void showStatusMessage(NameValidationStatus status) { errorLabel.getElement().getStyle().setColor(Style.getMainFontColor()); showMessage(status); } /** {@inheritDoc} */ @Override - public void showErrorMessage(RefactoringStatus status) { + public void showErrorMessage(NameValidationStatus status) { newName.addStyleName(javaResources.css().errorBorder()); errorLabel.getElement().getStyle().setColor(Style.getErrorColor()); showMessage(status); @@ -311,9 +311,10 @@ public String getFilePatterns() { return patternField.getValue(); } - private void showMessage(RefactoringStatus status) { + private void showMessage(NameValidationStatus status) { RefactoringStatusEntry statusEntry = - getEntryMatchingSeverity(status.getSeverity(), status.getEntries()); + getEntryMatchingSeverity( + status.getRefactoringSeverity().getValue(), status.getRefactoringStatusEntries()); if (statusEntry != null) { errorLabel.setText(statusEntry.getMessage()); } else { @@ -334,7 +335,7 @@ private void showMessage(RefactoringStatus status) { private RefactoringStatusEntry getEntryMatchingSeverity( int severity, List entries) { for (RefactoringStatusEntry entry : entries) { - if (entry.getSeverity() >= severity) return entry; + if (entry.getRefactoringSeverity().getValue() >= severity) return entry; } return null; } diff --git a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/similarnames/SimilarNamesConfigurationPresenter.java b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/similarnames/SimilarNamesConfigurationPresenter.java index 9b63db9cef00..18e931337764 100644 --- a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/similarnames/SimilarNamesConfigurationPresenter.java +++ b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/similarnames/SimilarNamesConfigurationPresenter.java @@ -13,7 +13,7 @@ import com.google.inject.Inject; import com.google.inject.Singleton; import org.eclipse.che.ide.ext.java.client.refactoring.rename.wizard.similarnames.SimilarNamesConfigurationView.ActionDelegate; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RenameSettings.MachStrategy; +import org.eclipse.che.jdt.ls.extension.api.MatchStrategy; /** * The class that manages similar name value. @@ -35,8 +35,8 @@ public void show() { view.showDialog(); } - /** @return selected value of mach strategy. */ - public MachStrategy getMachStrategy() { - return view.getMachStrategy(); + /** @return selected value of match strategy. */ + public MatchStrategy getMatchStrategy() { + return view.getMatchStrategy(); } } diff --git a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/similarnames/SimilarNamesConfigurationView.java b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/similarnames/SimilarNamesConfigurationView.java index 2f23d130b45e..9096e59c9cab 100644 --- a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/similarnames/SimilarNamesConfigurationView.java +++ b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/similarnames/SimilarNamesConfigurationView.java @@ -12,7 +12,7 @@ import com.google.inject.ImplementedBy; import org.eclipse.che.ide.api.mvp.View; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RenameSettings.MachStrategy; +import org.eclipse.che.jdt.ls.extension.api.MatchStrategy; /** * The visual part of Similar name wizard. @@ -22,7 +22,7 @@ @ImplementedBy(SimilarNamesConfigurationViewImpl.class) interface SimilarNamesConfigurationView extends View { - MachStrategy getMachStrategy(); + MatchStrategy getMatchStrategy(); /** Show Similar Names Configuration panel. */ void showDialog(); diff --git a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/similarnames/SimilarNamesConfigurationViewImpl.java b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/similarnames/SimilarNamesConfigurationViewImpl.java index a1c20544941c..12c6a580db95 100644 --- a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/similarnames/SimilarNamesConfigurationViewImpl.java +++ b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/similarnames/SimilarNamesConfigurationViewImpl.java @@ -19,8 +19,8 @@ import com.google.inject.Inject; import com.google.inject.Singleton; import org.eclipse.che.ide.ext.java.client.JavaLocalizationConstant; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RenameSettings.MachStrategy; import org.eclipse.che.ide.ui.window.Window; +import org.eclipse.che.jdt.ls.extension.api.MatchStrategy; /** @author Valeriy Svydenko */ @Singleton @@ -56,13 +56,13 @@ public SimilarNamesConfigurationViewImpl(JavaLocalizationConstant locale) { /** {@inheritDoc} */ @Override - public MachStrategy getMachStrategy() { + public MatchStrategy getMatchStrategy() { if (findExactNames.getValue()) { - return MachStrategy.EXACT; + return MatchStrategy.EXACT; } else if (findEmbeddedNames.getValue()) { - return MachStrategy.EMBEDDED; + return MatchStrategy.EMBEDDED; } else { - return MachStrategy.SUFFIX; + return MatchStrategy.SUFFIX; } } diff --git a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/service/JavaLanguageExtensionServiceClient.java b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/service/JavaLanguageExtensionServiceClient.java index e8ff7f29328f..b61794b29958 100644 --- a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/service/JavaLanguageExtensionServiceClient.java +++ b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/main/java/org/eclipse/che/ide/ext/java/client/service/JavaLanguageExtensionServiceClient.java @@ -21,14 +21,18 @@ import static org.eclipse.che.ide.ext.java.shared.Constants.EXTERNAL_LIBRARY_ENTRY; import static org.eclipse.che.ide.ext.java.shared.Constants.FILE_STRUCTURE; import static org.eclipse.che.ide.ext.java.shared.Constants.GET_JAVA_CORE_OPTIONS; +import static org.eclipse.che.ide.ext.java.shared.Constants.GET_LINKED_MODEL; import static org.eclipse.che.ide.ext.java.shared.Constants.IMPLEMENTERS; import static org.eclipse.che.ide.ext.java.shared.Constants.ORGANIZE_IMPORTS; import static org.eclipse.che.ide.ext.java.shared.Constants.RECOMPUTE_POM_DIAGNOSTICS; +import static org.eclipse.che.ide.ext.java.shared.Constants.REFACTORING_GET_RENAME_TYPE; +import static org.eclipse.che.ide.ext.java.shared.Constants.REFACTORING_RENAME; import static org.eclipse.che.ide.ext.java.shared.Constants.REIMPORT_MAVEN_PROJECTS; import static org.eclipse.che.ide.ext.java.shared.Constants.REIMPORT_MAVEN_PROJECTS_REQUEST_TIMEOUT; import static org.eclipse.che.ide.ext.java.shared.Constants.REQUEST_TIMEOUT; import static org.eclipse.che.ide.ext.java.shared.Constants.UPDATE_JAVA_CORE_OPTIONS; import static org.eclipse.che.ide.ext.java.shared.Constants.USAGES; +import static org.eclipse.che.ide.ext.java.shared.Constants.VALIDATE_RENAMED_NAME; import com.google.gwt.jsonp.client.TimeoutException; import com.google.inject.Inject; @@ -43,6 +47,7 @@ import org.eclipse.che.api.promises.client.js.RejectFunction; import org.eclipse.che.ide.api.app.AppContext; import org.eclipse.che.ide.api.workspace.WorkspaceReadyEvent; +import org.eclipse.che.jdt.ls.extension.api.dto.CheWorkspaceEdit; import org.eclipse.che.jdt.ls.extension.api.dto.ClasspathEntry; import org.eclipse.che.jdt.ls.extension.api.dto.ExtendedSymbolInformation; import org.eclipse.che.jdt.ls.extension.api.dto.ExternalLibrariesParameters; @@ -51,11 +56,16 @@ import org.eclipse.che.jdt.ls.extension.api.dto.Jar; import org.eclipse.che.jdt.ls.extension.api.dto.JarEntry; import org.eclipse.che.jdt.ls.extension.api.dto.JavaCoreOptions; +import org.eclipse.che.jdt.ls.extension.api.dto.NameValidationStatus; import org.eclipse.che.jdt.ls.extension.api.dto.OrganizeImportParams; import org.eclipse.che.jdt.ls.extension.api.dto.OrganizeImportsResult; import org.eclipse.che.jdt.ls.extension.api.dto.ReImportMavenProjectsCommandParameters; +import org.eclipse.che.jdt.ls.extension.api.dto.RenameSelectionParams; +import org.eclipse.che.jdt.ls.extension.api.dto.RenameSettings; +import org.eclipse.che.jdt.ls.extension.api.dto.RenamingElementInfo; import org.eclipse.che.jdt.ls.extension.api.dto.UsagesResponse; import org.eclipse.che.plugin.languageserver.ide.service.ServiceUtil; +import org.eclipse.lsp4j.Range; import org.eclipse.lsp4j.TextDocumentPositionParams; import org.eclipse.lsp4j.WorkspaceEdit; @@ -277,10 +287,70 @@ public Promise libraryEntry(String resourceUri) { .onFailure(error -> reject.apply(ServiceUtil.getPromiseError(error)))); } + /** Rename refactoring. */ + public Promise rename(RenameSettings renameSettings) { + return Promises.create( + (resolve, reject) -> + requestTransmitter + .newRequest() + .endpointId(WS_AGENT_JSON_RPC_ENDPOINT_ID) + .methodName(REFACTORING_RENAME) + .paramsAsDto(renameSettings) + .sendAndReceiveResultAsDto(CheWorkspaceEdit.class, REQUEST_TIMEOUT) + .onSuccess(resolve::apply) + .onTimeout(() -> onTimeout(reject)) + .onFailure(error -> reject.apply(ServiceUtil.getPromiseError(error)))); + } + + /** Returns type of Rename refactoring. */ + public Promise getRenameType(RenameSelectionParams renameSelection) { + return Promises.create( + (resolve, reject) -> + requestTransmitter + .newRequest() + .endpointId(WS_AGENT_JSON_RPC_ENDPOINT_ID) + .methodName(REFACTORING_GET_RENAME_TYPE) + .paramsAsDto(renameSelection) + .sendAndReceiveResultAsDto(RenamingElementInfo.class, REQUEST_TIMEOUT) + .onSuccess(resolve::apply) + .onTimeout(() -> onTimeout(reject)) + .onFailure(error -> reject.apply(ServiceUtil.getPromiseError(error)))); + } + + /** Validates new name. */ + public Promise validateRenamedName(RenameSelectionParams renameSelection) { + return Promises.create( + (resolve, reject) -> + requestTransmitter + .newRequest() + .endpointId(WS_AGENT_JSON_RPC_ENDPOINT_ID) + .methodName(VALIDATE_RENAMED_NAME) + .paramsAsDto(renameSelection) + .sendAndReceiveResultAsDto(NameValidationStatus.class, REQUEST_TIMEOUT) + .onSuccess(resolve::apply) + .onTimeout(() -> onTimeout(reject)) + .onFailure(error -> reject.apply(ServiceUtil.getPromiseError(error)))); + } + + /** Returns linked model. */ + public Promise> getLinkedModeModel(TextDocumentPositionParams linkedModelParams) { + return Promises.create( + (resolve, reject) -> + requestTransmitter + .newRequest() + .endpointId(WS_AGENT_JSON_RPC_ENDPOINT_ID) + .methodName(GET_LINKED_MODEL) + .paramsAsDto(linkedModelParams) + .sendAndReceiveResultAsListOfDto(Range.class, REQUEST_TIMEOUT) + .onSuccess(resolve::apply) + .onTimeout(() -> onTimeout(reject)) + .onFailure(error -> reject.apply(ServiceUtil.getPromiseError(error)))); + } + /** * Organize imports in a file or in all files in the specific directory. * - * @param path the path to the file or to the directory + * @param organizeImports parameters of the import operation * @return {@link WorkspaceEdit} changes to apply */ public Promise organizeImports(OrganizeImportParams organizeImports) { diff --git a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/test/java/org/eclipse/che/ide/ext/java/client/refactoring/preview/PreviewPresenterTest.java b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/test/java/org/eclipse/che/ide/ext/java/client/refactoring/preview/PreviewPresenterTest.java deleted file mode 100644 index 3b4771387fd1..000000000000 --- a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/test/java/org/eclipse/che/ide/ext/java/client/refactoring/preview/PreviewPresenterTest.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (c) 2012-2018 Red Hat, Inc. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Red Hat, Inc. - initial API and implementation - */ -package org.eclipse.che.ide.ext.java.client.refactoring.preview; - -import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus.OK; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyList; -import static org.mockito.ArgumentMatchers.anyObject; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.google.gwtmockito.GwtMockitoTestRunner; -import com.google.inject.Provider; -import java.util.ArrayList; -import java.util.List; -import org.eclipse.che.api.promises.client.Operation; -import org.eclipse.che.api.promises.client.Promise; -import org.eclipse.che.ide.api.editor.EditorAgent; -import org.eclipse.che.ide.api.editor.EditorInput; -import org.eclipse.che.ide.api.editor.EditorPartPresenter; -import org.eclipse.che.ide.api.editor.texteditor.TextEditor; -import org.eclipse.che.ide.api.filewatcher.ClientServerEventService; -import org.eclipse.che.ide.api.resources.VirtualFile; -import org.eclipse.che.ide.dto.DtoFactory; -import org.eclipse.che.ide.ext.java.client.refactoring.RefactorInfo; -import org.eclipse.che.ide.ext.java.client.refactoring.RefactoringUpdater; -import org.eclipse.che.ide.ext.java.client.refactoring.move.MoveType; -import org.eclipse.che.ide.ext.java.client.refactoring.move.wizard.MovePresenter; -import org.eclipse.che.ide.ext.java.client.refactoring.rename.wizard.RenamePresenter; -import org.eclipse.che.ide.ext.java.client.refactoring.service.RefactoringServiceClient; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.ChangeEnabledState; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.ChangeInfo; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.ChangePreview; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringChange; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringPreview; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringResult; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringSession; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; -import org.mockito.Mockito; - -/** @author Valeriy Svydenko */ -@RunWith(GwtMockitoTestRunner.class) -public class PreviewPresenterTest { - public static final String SESSION_ID = "sessionId"; - - @Mock private PreviewView view; - @Mock private Provider movePresenterProvider; - @Mock private Provider renamePresenterProvider; - @Mock private DtoFactory dtoFactory; - @Mock private RefactoringServiceClient refactoringService; - @Mock private EditorAgent editorAgent; - @Mock private RefactoringUpdater refactoringUpdater; - - @Mock private ChangeEnabledState changeEnableState; - @Mock private RefactoringChange refactoringChanges; - @Mock private RefactorInfo refactorInfo; - @Mock private RefactoringSession refactoringSession; - @Mock private RefactoringPreview refactoringPreview; - @Mock private EditorPartPresenter editor; - @Mock private Promise refactoringPreviewPromise; - @Mock private RefactoringResult refactoringStatus; - @Mock private TextEditor activeEditor; - @Mock private ChangePreview changePreview; - @Mock private Promise refactoringStatusPromise; - @Mock private Promise changePreviewPromise; - @Mock private Promise updateAfterRefactoringPromise; - @Mock private Promise fileTrackingSuspendEventPromise; - @Mock private Promise handleMovingFilesPromise; - @Mock private Promise changeEnableStatePromise; - @Mock private ClientServerEventService clientServerEventService; - - @Captor private ArgumentCaptor> refactoringPreviewOperation; - @Captor private ArgumentCaptor> refactoringStatusOperation; - @Captor private ArgumentCaptor> changePreviewOperation; - @Captor private ArgumentCaptor> changeEnableStateOperation; - @Captor private ArgumentCaptor> clientServerSuspendOperation; - - private PreviewPresenter presenter; - - @Before - public void setUp() throws Exception { - List editors = new ArrayList<>(); - editors.add(editor); - when(editorAgent.getActiveEditor()).thenReturn(activeEditor); - when(dtoFactory.createDto(RefactoringSession.class)).thenReturn(refactoringSession); - when(dtoFactory.createDto(ChangeEnabledState.class)).thenReturn(changeEnableState); - when(dtoFactory.createDto(RefactoringChange.class)).thenReturn(refactoringChanges); - when(refactoringService.getRefactoringPreview(refactoringSession)) - .thenReturn(refactoringPreviewPromise); - when(refactoringService.applyRefactoring(anyObject())).thenReturn(refactoringStatusPromise); - when(refactoringService.getChangePreview(refactoringChanges)).thenReturn(changePreviewPromise); - when(refactoringService.changeChangeEnabledState(changeEnableState)) - .thenReturn(changeEnableStatePromise); - when(editorAgent.getOpenedEditors()).thenReturn(editors); - when(clientServerEventService.sendFileTrackingSuspendEvent()) - .thenReturn(fileTrackingSuspendEventPromise); - List changes = new ArrayList<>(); - when(refactoringStatus.getChanges()).thenReturn(changes); - when(refactoringUpdater.handleMovingFiles(anyList())).thenReturn(handleMovingFilesPromise); - when(refactoringUpdater.updateAfterRefactoring(anyList())) - .thenReturn(updateAfterRefactoringPromise); - - presenter = - new PreviewPresenter( - view, - movePresenterProvider, - renamePresenterProvider, - dtoFactory, - editorAgent, - refactoringUpdater, - refactoringService, - clientServerEventService); - } - - @Test - public void constructorShouldBePerformed() throws Exception { - verify(view).setDelegate(presenter); - } - - @Test - public void viewShouldBeShowed() throws Exception { - presenter.show(SESSION_ID, refactorInfo); - - verify(refactoringSession).setSessionId(SESSION_ID); - verify(refactoringPreviewPromise).then(refactoringPreviewOperation.capture()); - refactoringPreviewOperation.getValue().apply(refactoringPreview); - verify(view).setTreeOfChanges(refactoringPreview); - verify(view).showDialog(); - } - - @Test - public void acceptButtonActionShouldBePerformed() throws Exception { - VirtualFile virtualFile = Mockito.mock(VirtualFile.class); - EditorInput editorInput = Mockito.mock(EditorInput.class); - when(refactoringStatus.getSeverity()).thenReturn(OK); - - when(editor.getEditorInput()).thenReturn(editorInput); - when(editorInput.getFile()).thenReturn(virtualFile); - - presenter.onAcceptButtonClicked(); - - verify(fileTrackingSuspendEventPromise).then(clientServerSuspendOperation.capture()); - clientServerSuspendOperation.getValue().apply(null); - verify(refactoringStatusPromise).then(refactoringStatusOperation.capture()); - refactoringStatusOperation.getValue().apply(refactoringStatus); - verify(clientServerEventService).sendFileTrackingResumeEvent(); - verify(refactoringUpdater).handleMovingFiles(anyList()); - verify(refactoringUpdater).updateAfterRefactoring(anyList()); - verify(view).close(); - } - - @Test - public void acceptButtonActionShouldBeNotPerformedIfStatusIsNotOK() throws Exception { - VirtualFile virtualFile = Mockito.mock(VirtualFile.class); - EditorInput editorInput = Mockito.mock(EditorInput.class); - when(refactoringStatus.getSeverity()).thenReturn(2); - when(editor.getEditorInput()).thenReturn(editorInput); - when(editorInput.getFile()).thenReturn(virtualFile); - - presenter.onAcceptButtonClicked(); - - verify(fileTrackingSuspendEventPromise).then(clientServerSuspendOperation.capture()); - clientServerSuspendOperation.getValue().apply(null); - verify(refactoringStatusPromise).then(refactoringStatusOperation.capture()); - refactoringStatusOperation.getValue().apply(refactoringStatus); - verify(clientServerEventService).sendFileTrackingResumeEvent(); - verify(refactoringUpdater).handleMovingFiles(anyList()); - verify(view, never()).close(); - verify(editor, never()).getEditorInput(); - verify(editorInput, never()).getFile(); - verify(virtualFile, never()).getLocation(); - verify(view).showErrorMessage(refactoringStatus); - } - - @Test - public void showMoveWizardIfOnBackButtonClicked() throws Exception { - MovePresenter movePresenter = Mockito.mock(MovePresenter.class); - when(refactorInfo.getMoveType()).thenReturn(MoveType.REFACTOR_MENU); - when(movePresenterProvider.get()).thenReturn(movePresenter); - - presenter.show(SESSION_ID, refactorInfo); - presenter.onBackButtonClicked(); - - verify(view).close(); - verify(movePresenter).show(refactorInfo); - } - - @Test - public void showRenameWizardIfOnBackButtonClicked() throws Exception { - RenamePresenter renamePresenter = Mockito.mock(RenamePresenter.class); - when(refactorInfo.getMoveType()).thenReturn(null); - when(renamePresenterProvider.get()).thenReturn(renamePresenter); - - presenter.show(SESSION_ID, refactorInfo); - presenter.onBackButtonClicked(); - - verify(view).close(); - verify(renamePresenter).show(refactorInfo); - } - - @Test - public void sendRequestToServerIfEnablingStateOfChangeIsChanging() throws Exception { - when(refactoringPreview.getId()).thenReturn("id"); - when(refactoringPreview.isEnabled()).thenReturn(true); - when(refactoringSession.getSessionId()).thenReturn(SESSION_ID); - - presenter.show(SESSION_ID, refactorInfo); - presenter.onEnabledStateChanged(refactoringPreview); - - verify(changeEnableState).setChangeId("id"); - changeEnableState.setSessionId(SESSION_ID); - changeEnableState.setEnabled(true); - - verify(changeEnableStatePromise).then(changeEnableStateOperation.capture()); - changeEnableStateOperation.getValue().apply(any()); - verify(refactoringChanges).setChangeId("id"); - verify(refactoringChanges).setSessionId(SESSION_ID); - verify(changePreviewPromise).then(changePreviewOperation.capture()); - changePreviewOperation.getValue().apply(changePreview); - verify(view).showDiff(changePreview); - } - - @Test - public void performIfSelectionChanged() throws Exception { - when(refactoringPreview.getId()).thenReturn("id"); - when(refactoringPreview.isEnabled()).thenReturn(true); - when(refactoringSession.getSessionId()).thenReturn(SESSION_ID); - - presenter.show(SESSION_ID, refactorInfo); - presenter.onSelectionChanged(refactoringPreview); - - verify(changePreviewPromise).then(changePreviewOperation.capture()); - changePreviewOperation.getValue().apply(changePreview); - verify(view).showDiff(changePreview); - } - - @Test - public void focusShouldBeSetAfterClosingTheEditor() throws Exception { - presenter.onCancelButtonClicked(); - - verify(activeEditor).setFocus(); - } -} diff --git a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/test/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/JavaRefactoringRenameTest.java b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/test/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/JavaRefactoringRenameTest.java deleted file mode 100644 index 08979e96e5ec..000000000000 --- a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/test/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/JavaRefactoringRenameTest.java +++ /dev/null @@ -1,471 +0,0 @@ -/* - * Copyright (c) 2012-2018 Red Hat, Inc. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Red Hat, Inc. - initial API and implementation - */ -package org.eclipse.che.ide.ext.java.client.refactoring.rename; - -import static org.eclipse.che.ide.api.editor.events.FileEvent.FileOperation.CLOSE; -import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.CreateRenameRefactoring.RenameType.JAVA_ELEMENT; -import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus.ERROR; -import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus.FATAL; -import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus.INFO; -import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus.OK; -import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus.WARNING; -import static org.junit.Assert.assertFalse; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyList; -import static org.mockito.ArgumentMatchers.anyObject; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.google.common.base.Optional; -import com.google.web.bindery.event.shared.EventBus; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import org.eclipse.che.api.promises.client.Operation; -import org.eclipse.che.api.promises.client.OperationException; -import org.eclipse.che.api.promises.client.Promise; -import org.eclipse.che.api.promises.client.PromiseError; -import org.eclipse.che.ide.api.editor.EditorInput; -import org.eclipse.che.ide.api.editor.EditorWithAutoSave; -import org.eclipse.che.ide.api.editor.document.Document; -import org.eclipse.che.ide.api.editor.events.FileEvent; -import org.eclipse.che.ide.api.editor.link.HasLinkedMode; -import org.eclipse.che.ide.api.editor.link.LinkedMode; -import org.eclipse.che.ide.api.editor.link.LinkedModel; -import org.eclipse.che.ide.api.editor.texteditor.HandlesUndoRedo; -import org.eclipse.che.ide.api.editor.texteditor.TextEditor; -import org.eclipse.che.ide.api.editor.texteditor.UndoableEditor; -import org.eclipse.che.ide.api.filewatcher.ClientServerEventService; -import org.eclipse.che.ide.api.notification.NotificationManager; -import org.eclipse.che.ide.api.resources.Container; -import org.eclipse.che.ide.api.resources.File; -import org.eclipse.che.ide.api.resources.Project; -import org.eclipse.che.ide.api.resources.Resource; -import org.eclipse.che.ide.dto.DtoFactory; -import org.eclipse.che.ide.ext.java.client.JavaLocalizationConstant; -import org.eclipse.che.ide.ext.java.client.refactoring.RefactoringUpdater; -import org.eclipse.che.ide.ext.java.client.refactoring.rename.wizard.RenamePresenter; -import org.eclipse.che.ide.ext.java.client.refactoring.service.RefactoringServiceClient; -import org.eclipse.che.ide.ext.java.client.resource.SourceFolderMarker; -import org.eclipse.che.ide.ext.java.shared.dto.LinkedModeModel; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.ChangeInfo; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.CreateRenameRefactoring; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.LinkedRenameRefactoringApply; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringResult; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatusEntry; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RenameRefactoringSession; -import org.eclipse.che.ide.resource.Path; -import org.eclipse.che.ide.ui.dialogs.CancelCallback; -import org.eclipse.che.ide.ui.dialogs.DialogFactory; -import org.eclipse.che.ide.ui.dialogs.confirm.ConfirmCallback; -import org.eclipse.che.ide.ui.dialogs.confirm.ConfirmDialog; -import org.eclipse.che.ide.ui.dialogs.message.MessageDialog; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnitRunner; - -/** - * @author Alexander Andrinko - * @author Vlad Zhukovskyi - */ -@RunWith(MockitoJUnitRunner.class) -public class JavaRefactoringRenameTest { - - private static final String NEW_JAVA_CLASS_NAME = "NewJavaTest.java"; - private static final String SESSION_ID = "some session id"; - private static final int CURSOR_OFFSET = 10; - - // variables for constructor - @Mock private RenamePresenter renamePresenter; - @Mock private JavaLocalizationConstant locale; - @Mock private DialogFactory dialogFactory; - @Mock private RefactoringServiceClient refactoringServiceClient; - @Mock private DtoFactory dtoFactory; - @Mock private RefactoringUpdater refactoringUpdater; - @Mock private NotificationManager notificationManager; - @Mock private ClientServerEventService clientServerEventService; - - @Mock private CreateRenameRefactoring createRenameRefactoringDto; - @Mock private LinkedRenameRefactoringApply linkedRenameRefactoringApplyDto; - - @Mock(extraInterfaces = {HasLinkedMode.class, EditorWithAutoSave.class, UndoableEditor.class}) - private TextEditor textEditor; - - @Mock private EditorInput editorInput; - @Mock private File file; - @Mock private Container srcFolder; - @Mock private Project relatedProject; - @Mock private Promise createRenamePromise; - @Mock private RenameRefactoringSession session; - @Mock private LinkedModeModel linkedModel; - @Mock private Promise applyModelPromise; - @Mock private RefactoringResult result; - @Mock private FileEvent fileEvent; - @Mock private RefactoringStatusEntry entry; - @Mock private LinkedMode linkedMode; - @Mock private LinkedModel editorLinkedModel; - @Mock private EventBus eventBus; - @Mock private Document document; - @Mock private HandlesUndoRedo undoRedo; - @Mock private Promise updateAfterRefactoringPromise; - @Mock private Promise fileTrackingSuspendEventPromise; - @Mock private Promise fileTrackingResumeEventPromise; - @Mock private Promise handleMovingFilesPromise; - - @Captor private ArgumentCaptor> renameRefCaptor; - @Captor private ArgumentCaptor inputArgumentCaptor; - @Captor private ArgumentCaptor> refactoringStatusCaptor; - @Captor private ArgumentCaptor> refactoringErrorCaptor; - @Captor private ArgumentCaptor> clientServerSuspendOperation; - @Captor private ArgumentCaptor> clientServerResumeOperation; - @Captor private ArgumentCaptor> updateAfterRefactoringOperation; - - @InjectMocks private JavaRefactoringRename refactoringRename; - - @Before - public void setUp() { - when(dtoFactory.createDto(CreateRenameRefactoring.class)) - .thenReturn(createRenameRefactoringDto); - when(dtoFactory.createDto(LinkedRenameRefactoringApply.class)) - .thenReturn(linkedRenameRefactoringApplyDto); - when(textEditor.getEditorInput()).thenReturn(editorInput); - when(editorInput.getFile()).thenReturn(file); - when(file.getName()).thenReturn("A.java"); - when(file.getExtension()).thenReturn("java"); - when(file.getParentWithMarker(eq(SourceFolderMarker.ID))).thenReturn(Optional.of(srcFolder)); - when(file.getLocation()).thenReturn(Path.valueOf("/project/src/a/b/c/A.java")); - when(file.getResourceType()).thenReturn(Resource.FILE); - when(srcFolder.getLocation()).thenReturn(Path.valueOf("/project/src")); - when(file.getRelatedProject()).thenReturn(Optional.of(relatedProject)); - when(relatedProject.getLocation()).thenReturn(Path.valueOf("/project")); - when(refactoringServiceClient.createRenameRefactoring(createRenameRefactoringDto)) - .thenReturn(createRenamePromise); - when(createRenamePromise.then((Operation) any())) - .thenReturn(createRenamePromise); - when(applyModelPromise.then((Operation) any())) - .thenReturn(applyModelPromise); - when(session.getLinkedModeModel()).thenReturn(linkedModel); - when(refactoringServiceClient.applyLinkedModeRename(linkedRenameRefactoringApplyDto)) - .thenReturn(applyModelPromise); - when(textEditor.getCursorOffset()).thenReturn(CURSOR_OFFSET); - when(document.getContentRange(anyInt(), anyInt())).thenReturn(NEW_JAVA_CLASS_NAME); - when(((HasLinkedMode) textEditor).getLinkedMode()).thenReturn(linkedMode); - when(((HasLinkedMode) textEditor).createLinkedModel()).thenReturn(editorLinkedModel); - when(textEditor.getDocument()).thenReturn(document); - when(document.getFile()).thenReturn(file); - - when(result.getEntries()).thenReturn(Collections.singletonList(entry)); - - when(clientServerEventService.sendFileTrackingSuspendEvent()) - .thenReturn(fileTrackingSuspendEventPromise); - when(clientServerEventService.sendFileTrackingResumeEvent()) - .thenReturn(fileTrackingResumeEventPromise); - when(refactoringUpdater.handleMovingFiles(anyList())).thenReturn(handleMovingFilesPromise); - when(refactoringUpdater.updateAfterRefactoring(anyList())) - .thenReturn(updateAfterRefactoringPromise); - when(((UndoableEditor) textEditor).getUndoRedo()).thenReturn(undoRedo); - } - - @Test - public void renameRefactoringShouldBeAppliedSuccess() throws OperationException { - when(result.getSeverity()).thenReturn(OK); - List changes = new ArrayList<>(); - when(result.getChanges()).thenReturn(changes); - - refactoringRename.refactor(textEditor); - - mainCheckRenameRefactoring(); - - verify(refactoringUpdater) - .updateAfterRefactoring(org.mockito.ArgumentMatchers.>any()); - verify(eventBus).addHandler(FileEvent.TYPE, refactoringRename); - - verify(updateAfterRefactoringPromise).then(updateAfterRefactoringOperation.capture()); - updateAfterRefactoringOperation.getValue().apply(null); - verify(refactoringUpdater).handleMovingFiles(anyList()); - verify(clientServerEventService).sendFileTrackingResumeEvent(); - } - - @Test - public void turnOffLinkedEditorModeWhenEditorIsClosed() throws Exception { - when(fileEvent.getOperationType()).thenReturn(CLOSE); - when(fileEvent.getFile()).thenReturn(file); - - refactoringRename.refactor(textEditor); - refactoringRename.onFileOperation(fileEvent); - - assertFalse(refactoringRename.isActiveLinkedEditor()); - } - - @Test - public void renameRefactoringShouldBeAppliedSuccessAndShowWizard() throws OperationException { - refactoringRename.refactor(textEditor); - refactoringRename.refactor(textEditor); - - verify(refactoringServiceClient, times(2)).createRenameRefactoring(createRenameRefactoringDto); - verify(createRenamePromise, times(2)).then(renameRefCaptor.capture()); - renameRefCaptor.getValue().apply(session); - verify(renamePresenter).show(session); - } - - @Test - public void renameRefactoringShouldBeShowErrorWindow() throws OperationException { - PromiseError arg = Mockito.mock(PromiseError.class); - MessageDialog dialog = Mockito.mock(MessageDialog.class); - - when(locale.renameRename()).thenReturn("renameTitle"); - when(locale.renameOperationUnavailable()).thenReturn("renameBody"); - when(dialogFactory.createMessageDialog(anyString(), anyString(), anyObject())) - .thenReturn(dialog); - - refactoringRename.refactor(textEditor); - - verify(createRenamePromise).then(renameRefCaptor.capture()); - renameRefCaptor.getValue().apply(session); - verify(createRenamePromise).catchError(refactoringErrorCaptor.capture()); - refactoringErrorCaptor.getValue().apply(arg); - - verify(dialogFactory).createMessageDialog("renameTitle", "renameBody", null); - verify(dialog).show(); - } - - @Test - public void renameRefactoringShouldBeFailedByFatalError() throws OperationException { - when(result.getSeverity()).thenReturn(FATAL); - - refactoringRename.refactor(textEditor); - - mainCheckRenameRefactoring(); - verify(result, times(1)).getSeverity(); - verify(clientServerEventService).sendFileTrackingResumeEvent(); - } - - @Test - public void renameRefactoringShouldBeFailedByError() throws OperationException { - ConfirmDialog confirmDialog = mock(ConfirmDialog.class); - when(result.getSeverity()).thenReturn(ERROR); - - when(dialogFactory.createConfirmDialog( - nullable(String.class), - nullable(String.class), - nullable(String.class), - nullable(String.class), - nullable(ConfirmCallback.class), - nullable(CancelCallback.class))) - .thenReturn(confirmDialog); - - refactoringRename.refactor(textEditor); - - verify(refactoringServiceClient).createRenameRefactoring(createRenameRefactoringDto); - verify(createRenamePromise).then(renameRefCaptor.capture()); - renameRefCaptor.getValue().apply(session); - - verify(fileTrackingSuspendEventPromise).then(clientServerSuspendOperation.capture()); - clientServerSuspendOperation.getValue().apply(null); - - verify(linkedMode).addListener(inputArgumentCaptor.capture()); - inputArgumentCaptor.getValue().onLinkedModeExited(true, 0, 1); - - verify(refactoringServiceClient).applyLinkedModeRename(linkedRenameRefactoringApplyDto); - - verify(applyModelPromise).then(refactoringStatusCaptor.capture()); - refactoringStatusCaptor.getValue().apply(result); - - verify(locale).warningOperationTitle(); - verify(locale).renameWithWarnings(); - verify(locale).showRenameWizard(); - verify(locale).buttonCancel(); - verify(dialogFactory) - .createConfirmDialog( - nullable(String.class), - nullable(String.class), - nullable(String.class), - nullable(String.class), - org.mockito.ArgumentMatchers.anyObject(), - org.mockito.ArgumentMatchers.anyObject()); - verify(confirmDialog).show(); - } - - @Test - public void renameRefactoringShouldBeWithWarningOrErrorStatus() throws OperationException { - ConfirmDialog confirmDialog = mock(ConfirmDialog.class); - - when(result.getSeverity()).thenReturn(WARNING); - when(dialogFactory.createConfirmDialog( - nullable(String.class), - nullable(String.class), - nullable(String.class), - nullable(String.class), - nullable(ConfirmCallback.class), - nullable(CancelCallback.class))) - .thenReturn(confirmDialog); - - refactoringRename.refactor(textEditor); - - verify(refactoringServiceClient).createRenameRefactoring(createRenameRefactoringDto); - verify(createRenamePromise).then(renameRefCaptor.capture()); - renameRefCaptor.getValue().apply(session); - - verify(fileTrackingSuspendEventPromise).then(clientServerSuspendOperation.capture()); - clientServerSuspendOperation.getValue().apply(null); - - verify(linkedMode).addListener(inputArgumentCaptor.capture()); - inputArgumentCaptor.getValue().onLinkedModeExited(true, 0, 1); - - verify(refactoringServiceClient).applyLinkedModeRename(linkedRenameRefactoringApplyDto); - - verify(applyModelPromise).then(refactoringStatusCaptor.capture()); - refactoringStatusCaptor.getValue().apply(result); - - verify(locale).warningOperationTitle(); - verify(locale).renameWithWarnings(); - verify(locale).showRenameWizard(); - verify(locale).buttonCancel(); - verify(dialogFactory) - .createConfirmDialog( - nullable(String.class), - nullable(String.class), - nullable(String.class), - nullable(String.class), - org.mockito.ArgumentMatchers.anyObject(), - org.mockito.ArgumentMatchers.anyObject()); - verify(confirmDialog).show(); - } - - @Test - public void renameRefactoringShouldBeWithINFO() throws OperationException { - when(result.getSeverity()).thenReturn(INFO); - - refactoringRename.refactor(textEditor); - - mainCheckRenameRefactoring(); - verify(result).getSeverity(); - - verify(updateAfterRefactoringPromise).then(updateAfterRefactoringOperation.capture()); - updateAfterRefactoringOperation.getValue().apply(null); - verify(refactoringUpdater).handleMovingFiles(anyList()); - verify(clientServerEventService).sendFileTrackingResumeEvent(); - } - - @Test - public void renameRefactoringShouldBeWithOK() throws OperationException { - when(result.getSeverity()).thenReturn(OK); - - refactoringRename.refactor(textEditor); - - mainCheckRenameRefactoring(); - verify(result).getSeverity(); - - verify(updateAfterRefactoringPromise).then(updateAfterRefactoringOperation.capture()); - updateAfterRefactoringOperation.getValue().apply(null); - verify(refactoringUpdater).handleMovingFiles(anyList()); - verify(clientServerEventService).sendFileTrackingResumeEvent(); - } - - @Test - public void shouldUndoRenameRefactoringWhenUserEnterNewNameButEscapeRename() - throws OperationException { - // use case: user hit Refactoring -> Rename action, type a new name and press escape button - - refactoringRename.refactor(textEditor); - - verify(refactoringServiceClient).createRenameRefactoring(createRenameRefactoringDto); - verify(createRenamePromise).then(renameRefCaptor.capture()); - renameRefCaptor.getValue().apply(session); - - verify(fileTrackingSuspendEventPromise).then(clientServerSuspendOperation.capture()); - clientServerSuspendOperation.getValue().apply(null); - - verify(linkedMode).addListener(inputArgumentCaptor.capture()); - inputArgumentCaptor.getValue().onLinkedModeExited(false, 0, 5); - - verify(fileTrackingResumeEventPromise).then(clientServerResumeOperation.capture()); - clientServerResumeOperation.getValue().apply(null); - - verify(refactoringServiceClient, never()).applyLinkedModeRename(anyObject()); - verify((UndoableEditor) textEditor).getUndoRedo(); - verify(undoRedo).undo(); - verify((EditorWithAutoSave) textEditor).enableAutoSave(); - } - - @Test - public void shouldDoNotApplyUndoOperationWhenUserNotEnterNewNameAndEscapeRename() - throws OperationException { - // use case: user hit Refactoring -> Rename action, DO NOT type a new name and press escape - // button - - refactoringRename.refactor(textEditor); - - verify(refactoringServiceClient).createRenameRefactoring(createRenameRefactoringDto); - verify(createRenamePromise).then(renameRefCaptor.capture()); - renameRefCaptor.getValue().apply(session); - - verify(fileTrackingSuspendEventPromise).then(clientServerSuspendOperation.capture()); - clientServerSuspendOperation.getValue().apply(null); - - verify(linkedMode).addListener(inputArgumentCaptor.capture()); - inputArgumentCaptor.getValue().onLinkedModeExited(false, -1, -1); - - verify(fileTrackingResumeEventPromise).then(clientServerResumeOperation.capture()); - clientServerResumeOperation.getValue().apply(null); - - verify(refactoringServiceClient, never()).applyLinkedModeRename(anyObject()); - verify((UndoableEditor) textEditor, never()).getUndoRedo(); - verify(undoRedo, never()).undo(); - verify((EditorWithAutoSave) textEditor).enableAutoSave(); - } - - private void mainCheckRenameRefactoring() throws OperationException { - verify(dtoFactory).createDto(CreateRenameRefactoring.class); - verify(textEditor).getCursorOffset(); - verify(createRenameRefactoringDto).setOffset(CURSOR_OFFSET); - verify(createRenameRefactoringDto).setRefactorLightweight(true); - verify(textEditor).getEditorInput(); - verify(editorInput).getFile(); - verify(createRenameRefactoringDto).setPath(eq("a.b.c.A")); - verify(createRenameRefactoringDto).setProjectPath(eq("/project")); - verify(createRenameRefactoringDto).setProjectPath(eq("/project")); - verify(createRenameRefactoringDto).setType(JAVA_ELEMENT); - - verify(refactoringServiceClient).createRenameRefactoring(createRenameRefactoringDto); - verify(createRenamePromise).then(renameRefCaptor.capture()); - renameRefCaptor.getValue().apply(session); - - verify(fileTrackingSuspendEventPromise).then(clientServerSuspendOperation.capture()); - clientServerSuspendOperation.getValue().apply(null); - - verify(session).getLinkedModeModel(); - - verify(linkedMode).addListener(inputArgumentCaptor.capture()); - inputArgumentCaptor.getValue().onLinkedModeExited(true, 0, 1); - verify(dtoFactory).createDto(LinkedRenameRefactoringApply.class); - linkedRenameRefactoringApplyDto.setNewName(NEW_JAVA_CLASS_NAME); - linkedRenameRefactoringApplyDto.setSessionId(SESSION_ID); - - verify(refactoringServiceClient).applyLinkedModeRename(linkedRenameRefactoringApplyDto); - - verify(applyModelPromise).then(refactoringStatusCaptor.capture()); - refactoringStatusCaptor.getValue().apply(result); - } -} diff --git a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/test/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/RenamePresenterTest.java b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/test/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/RenamePresenterTest.java deleted file mode 100644 index 9e0ec670ae31..000000000000 --- a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/test/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/RenamePresenterTest.java +++ /dev/null @@ -1,812 +0,0 @@ -/* - * Copyright (c) 2012-2018 Red Hat, Inc. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Red Hat, Inc. - initial API and implementation - */ -package org.eclipse.che.ide.ext.java.client.refactoring.rename.wizard; - -import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.CreateRenameRefactoring.RenameType.COMPILATION_UNIT; -import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.CreateRenameRefactoring.RenameType.JAVA_ELEMENT; -import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.CreateRenameRefactoring.RenameType.PACKAGE; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyList; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.google.common.base.Optional; -import com.google.gwtmockito.GwtMockitoTestRunner; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import org.eclipse.che.api.promises.client.Function; -import org.eclipse.che.api.promises.client.FunctionException; -import org.eclipse.che.api.promises.client.Operation; -import org.eclipse.che.api.promises.client.OperationException; -import org.eclipse.che.api.promises.client.Promise; -import org.eclipse.che.api.promises.client.PromiseError; -import org.eclipse.che.ide.api.app.AppContext; -import org.eclipse.che.ide.api.editor.EditorAgent; -import org.eclipse.che.ide.api.editor.EditorInput; -import org.eclipse.che.ide.api.editor.texteditor.TextEditor; -import org.eclipse.che.ide.api.filewatcher.ClientServerEventService; -import org.eclipse.che.ide.api.notification.NotificationManager; -import org.eclipse.che.ide.api.notification.StatusNotification; -import org.eclipse.che.ide.api.notification.StatusNotification.DisplayMode; -import org.eclipse.che.ide.api.resources.Container; -import org.eclipse.che.ide.api.resources.File; -import org.eclipse.che.ide.api.resources.Project; -import org.eclipse.che.ide.api.resources.Resource; -import org.eclipse.che.ide.dto.DtoFactory; -import org.eclipse.che.ide.ext.java.client.JavaLocalizationConstant; -import org.eclipse.che.ide.ext.java.client.refactoring.RefactorInfo; -import org.eclipse.che.ide.ext.java.client.refactoring.RefactoringUpdater; -import org.eclipse.che.ide.ext.java.client.refactoring.move.MoveType; -import org.eclipse.che.ide.ext.java.client.refactoring.move.RefactoredItemType; -import org.eclipse.che.ide.ext.java.client.refactoring.preview.PreviewPresenter; -import org.eclipse.che.ide.ext.java.client.refactoring.rename.wizard.similarnames.SimilarNamesConfigurationPresenter; -import org.eclipse.che.ide.ext.java.client.refactoring.service.RefactoringServiceClient; -import org.eclipse.che.ide.ext.java.client.resource.SourceFolderMarker; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.ChangeCreationResult; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.ChangeInfo; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.CreateRenameRefactoring; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringResult; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringSession; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatusEntry; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RenameRefactoringSession; -import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RenameSettings; -import org.eclipse.che.ide.resource.Path; -import org.eclipse.che.ide.ui.dialogs.CancelCallback; -import org.eclipse.che.ide.ui.dialogs.DialogFactory; -import org.eclipse.che.ide.ui.dialogs.confirm.ConfirmCallback; -import org.eclipse.che.ide.ui.dialogs.confirm.ConfirmDialog; -import org.eclipse.che.ide.ui.loaders.request.LoaderFactory; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; - -@RunWith(GwtMockitoTestRunner.class) -public class RenamePresenterTest { - private static final String SESSION_ID = "sessionId"; - private static final String TEXT = "text.text"; - - // variables for constructor - @Mock private RenameView view; - @Mock private SimilarNamesConfigurationPresenter similarNamesConfigurationPresenter; - @Mock private JavaLocalizationConstant locale; - @Mock private EditorAgent editorAgent; - @Mock private RefactoringUpdater refactoringUpdater; - @Mock private NotificationManager notificationManager; - @Mock private AppContext appContext; - @Mock private PreviewPresenter previewPresenter; - @Mock private DtoFactory dtoFactory; - @Mock private RefactoringServiceClient refactorService; - @Mock private LoaderFactory loaderFactory; - @Mock private ClientServerEventService clientServerEventService; - - @Mock private TextEditor activeEditor; - @Mock private EditorInput editorInput; - @Mock private File file; - @Mock private Container container; - @Mock private Container srcFolder; - @Mock private Project project; - @Mock private RefactoringSession refactoringSession; - @Mock private RenameSettings renameSettings; - @Mock private RefactoringResult refactoringStatus; - @Mock private CreateRenameRefactoring createRenameRefactoringDto; - @Mock private PromiseError promiseError; - @Mock private ChangeCreationResult changeCreationResult; - @Mock private RenameRefactoringSession session; - @Mock private DialogFactory dialogFactory; - - @Mock private Promise renameRefactoringSessionPromise; - @Mock private Promise renameSettingsPromise; - @Mock private Promise changeCreationResultPromise; - @Mock private Promise refactoringStatusPromise; - @Mock private Promise updateAfterRefactoringPromise; - @Mock private Promise fileTrackingSuspendEventPromise; - @Mock private Promise handleMovingFilesPromise; - - @Captor - private ArgumentCaptor> renameRefactoringSessionCaptor; - - @Captor private ArgumentCaptor> promiseErrorCaptor; - - @Captor - private ArgumentCaptor>> renameSettingsPromiseCaptor; - - @Captor private ArgumentCaptor> changeCreationResultCaptor; - @Captor private ArgumentCaptor> refactoringStatusCaptor; - @Captor private ArgumentCaptor> clientServerSuspendOperation; - @Captor private ArgumentCaptor> updateAfterRefactoringOperation; - - private RenamePresenter renamePresenter; - - private RefactorInfo refactorInfo; - - @Before - public void setUp() throws Exception { - when(editorAgent.getActiveEditor()).thenReturn(activeEditor); - when(activeEditor.getEditorInput()).thenReturn(editorInput); - when(editorInput.getFile()).thenReturn(file); - when(file.getRelatedProject()).thenReturn(Optional.of(project)); - when(file.getParentWithMarker(eq(SourceFolderMarker.ID))).thenReturn(Optional.of(srcFolder)); - when(file.getName()).thenReturn("A.java"); - when(file.getExtension()).thenReturn("java"); - when(file.getLocation()).thenReturn(Path.valueOf("/project/src/a/b/c/A.java")); - when(file.getResourceType()).thenReturn(Resource.FILE); - when(srcFolder.getLocation()).thenReturn(Path.valueOf("/project/src")); - when(project.getLocation()).thenReturn(Path.valueOf("/project")); - when(dtoFactory.createDto(CreateRenameRefactoring.class)) - .thenReturn(createRenameRefactoringDto); - when(container.getLocation()).thenReturn(Path.valueOf("/project/src/a/b/c")); - when(container.getRelatedProject()).thenReturn(Optional.of(project)); - when(dtoFactory.createDto(RefactoringSession.class)).thenReturn(refactoringSession); - when(dtoFactory.createDto(RenameSettings.class)).thenReturn(renameSettings); - when(refactoringSession.getSessionId()).thenReturn(SESSION_ID); - when(session.getOldName()).thenReturn(TEXT); - when(session.getSessionId()).thenReturn(SESSION_ID); - when(refactorService.createRenameRefactoring(createRenameRefactoringDto)) - .thenReturn(renameRefactoringSessionPromise); - when(session.getWizardType()).thenReturn(RenameRefactoringSession.RenameWizard.LOCAL_VARIABLE); - when(renameRefactoringSessionPromise.then( - org.mockito.ArgumentMatchers.>anyObject())) - .thenReturn(renameRefactoringSessionPromise); - when(view.isUpdateDelegateUpdating()).thenReturn(true); - when(view.isUpdateQualifiedNames()).thenReturn(true); - when(view.isUpdateSimilarlyVariables()).thenReturn(true); - when(similarNamesConfigurationPresenter.getMachStrategy()) - .thenReturn(RenameSettings.MachStrategy.SUFFIX); - when(refactorService.setRenameSettings(renameSettings)).thenReturn(renameSettingsPromise); - when(renameSettingsPromise.thenPromise( - org.mockito.ArgumentMatchers.>>any())) - .thenReturn(changeCreationResultPromise); - when(changeCreationResultPromise.then( - org.mockito.ArgumentMatchers.>any())) - .thenReturn(changeCreationResultPromise); - when(changeCreationResultPromise.catchError( - org.mockito.ArgumentMatchers.>anyObject())) - .thenReturn(changeCreationResultPromise); - when(refactorService.applyRefactoring(refactoringSession)).thenReturn(refactoringStatusPromise); - - when(changeCreationResult.getStatus()).thenReturn(refactoringStatus); - - when(clientServerEventService.sendFileTrackingSuspendEvent()) - .thenReturn(fileTrackingSuspendEventPromise); - when(refactoringUpdater.handleMovingFiles(anyList())).thenReturn(handleMovingFilesPromise); - when(refactoringUpdater.updateAfterRefactoring(anyList())) - .thenReturn(updateAfterRefactoringPromise); - when(updateAfterRefactoringPromise.then( - org.mockito.ArgumentMatchers.>anyObject())) - .thenReturn(updateAfterRefactoringPromise); - - renamePresenter = - new RenamePresenter( - view, - similarNamesConfigurationPresenter, - locale, - editorAgent, - refactoringUpdater, - appContext, - notificationManager, - previewPresenter, - refactorService, - clientServerEventService, - dtoFactory, - dialogFactory); - } - - @Test - public void wizardShouldNotBeShowIfRenameRefactoringObjectWasNotCreated() throws Exception { - RefactorInfo refactorInfo = - RefactorInfo.of( - MoveType.REFACTOR_MENU, RefactoredItemType.COMPILATION_UNIT, new Resource[] {file}); - - renamePresenter.show(refactorInfo); - - verify(createRenameRefactoringDto).setRefactorLightweight(false); - verify(createRenameRefactoringDto).setPath(nullable(String.class)); - verify(createRenameRefactoringDto).setType(COMPILATION_UNIT); - verify(createRenameRefactoringDto).setProjectPath(eq("/project")); - - verify(refactorService).createRenameRefactoring(createRenameRefactoringDto); - verify(renameRefactoringSessionPromise).catchError(promiseErrorCaptor.capture()); - promiseErrorCaptor.getValue().apply(promiseError); - verify(notificationManager) - .notify( - nullable(String.class), - nullable(String.class), - any(StatusNotification.Status.class), - any(DisplayMode.class)); - } - - @Test - public void renameCompilationUnitWizardShouldBeShowCompilationUnit() throws Exception { - when(session.getWizardType()) - .thenReturn(RenameRefactoringSession.RenameWizard.COMPILATION_UNIT); - - RefactorInfo refactorInfo = - RefactorInfo.of( - MoveType.REFACTOR_MENU, RefactoredItemType.COMPILATION_UNIT, new Resource[] {file}); - - renamePresenter.show(refactorInfo); - - verifyPreparingRenameRefactoringDto(); - - verify(refactorService).createRenameRefactoring(createRenameRefactoringDto); - verify(renameRefactoringSessionPromise).then(renameRefactoringSessionCaptor.capture()); - renameRefactoringSessionCaptor.getValue().apply(session); - - verifyPreparingWizard(); - - verify(locale).renameCompilationUnitTitle(); - verify(view).setTitleCaption(nullable(String.class)); - verify(view).setVisiblePatternsPanel(true); - verify(view).setVisibleFullQualifiedNamePanel(true); - verify(view).setVisibleSimilarlyVariablesPanel(true); - - verify(view).showDialog(); - } - - @Test - public void renamePackageWizardShouldBeShow() throws Exception { - when(session.getWizardType()).thenReturn(RenameRefactoringSession.RenameWizard.PACKAGE); - - RefactorInfo refactorInfo = - RefactorInfo.of( - MoveType.REFACTOR_MENU, RefactoredItemType.COMPILATION_UNIT, new Resource[] {file}); - - renamePresenter.show(refactorInfo); - - verifyPreparingRenameRefactoringDto(); - - verify(refactorService).createRenameRefactoring(createRenameRefactoringDto); - verify(renameRefactoringSessionPromise).then(renameRefactoringSessionCaptor.capture()); - renameRefactoringSessionCaptor.getValue().apply(session); - - verifyPreparingWizard(); - - verify(locale).renamePackageTitle(); - verify(view).setTitleCaption(nullable(String.class)); - verify(view).setVisiblePatternsPanel(true); - verify(view).setVisibleFullQualifiedNamePanel(true); - verify(view).setVisibleRenameSubpackagesPanel(true); - - verify(view).showDialog(); - } - - @Test - public void renameTypeWizardShouldBeShow() throws Exception { - when(session.getWizardType()).thenReturn(RenameRefactoringSession.RenameWizard.TYPE); - - RefactorInfo refactorInfo = - RefactorInfo.of( - MoveType.REFACTOR_MENU, RefactoredItemType.COMPILATION_UNIT, new Resource[] {file}); - - renamePresenter.show(refactorInfo); - - verifyPreparingRenameRefactoringDto(); - - verify(refactorService).createRenameRefactoring(createRenameRefactoringDto); - verify(renameRefactoringSessionPromise).then(renameRefactoringSessionCaptor.capture()); - renameRefactoringSessionCaptor.getValue().apply(session); - - verifyPreparingWizard(); - - verify(locale).renameTypeTitle(); - verify(view).setTitleCaption(nullable(String.class)); - verify(view).setVisiblePatternsPanel(true); - verify(view).setVisibleFullQualifiedNamePanel(true); - verify(view).setVisibleSimilarlyVariablesPanel(true); - - verify(view).showDialog(); - } - - @Test - public void renameFieldWizardShouldBeShow() throws Exception { - when(session.getWizardType()).thenReturn(RenameRefactoringSession.RenameWizard.FIELD); - - RefactorInfo refactorInfo = - RefactorInfo.of( - MoveType.REFACTOR_MENU, RefactoredItemType.COMPILATION_UNIT, new Resource[] {file}); - - renamePresenter.show(refactorInfo); - - verifyPreparingRenameRefactoringDto(); - - verify(refactorService).createRenameRefactoring(createRenameRefactoringDto); - verify(renameRefactoringSessionPromise).then(renameRefactoringSessionCaptor.capture()); - renameRefactoringSessionCaptor.getValue().apply(session); - - verifyPreparingWizard(); - - verify(locale).renameFieldTitle(); - verify(view).setTitleCaption(nullable(String.class)); - verify(view).setVisiblePatternsPanel(true); - - verify(view).showDialog(); - } - - @Test - public void renameEnumConstantWizardShouldBeShow() throws Exception { - when(session.getWizardType()).thenReturn(RenameRefactoringSession.RenameWizard.ENUM_CONSTANT); - - RefactorInfo refactorInfo = - RefactorInfo.of( - MoveType.REFACTOR_MENU, RefactoredItemType.COMPILATION_UNIT, new Resource[] {file}); - - renamePresenter.show(refactorInfo); - - verifyPreparingRenameRefactoringDto(); - - verify(refactorService).createRenameRefactoring(createRenameRefactoringDto); - verify(renameRefactoringSessionPromise).then(renameRefactoringSessionCaptor.capture()); - renameRefactoringSessionCaptor.getValue().apply(session); - - verifyPreparingWizard(); - - verify(locale).renameEnumTitle(); - verify(view).setTitleCaption(nullable(String.class)); - verify(view).setVisiblePatternsPanel(true); - - verify(view).showDialog(); - } - - @Test - public void renameTypeParameterWizardShouldBeShow() throws Exception { - when(session.getWizardType()).thenReturn(RenameRefactoringSession.RenameWizard.TYPE_PARAMETER); - - RefactorInfo refactorInfo = - RefactorInfo.of( - MoveType.REFACTOR_MENU, RefactoredItemType.COMPILATION_UNIT, new Resource[] {file}); - - renamePresenter.show(refactorInfo); - - verifyPreparingRenameRefactoringDto(); - - verify(refactorService).createRenameRefactoring(createRenameRefactoringDto); - verify(renameRefactoringSessionPromise).then(renameRefactoringSessionCaptor.capture()); - renameRefactoringSessionCaptor.getValue().apply(session); - - verifyPreparingWizard(); - - verify(locale).renameTypeVariableTitle(); - verify(view).setTitleCaption(nullable(String.class)); - - verify(view).showDialog(); - } - - @Test - public void renameMethodWizardShouldBeShow() throws Exception { - when(session.getWizardType()).thenReturn(RenameRefactoringSession.RenameWizard.METHOD); - - RefactorInfo refactorInfo = - RefactorInfo.of( - MoveType.REFACTOR_MENU, RefactoredItemType.COMPILATION_UNIT, new Resource[] {file}); - - renamePresenter.show(refactorInfo); - - verifyPreparingRenameRefactoringDto(); - - verify(refactorService).createRenameRefactoring(createRenameRefactoringDto); - verify(renameRefactoringSessionPromise).then(renameRefactoringSessionCaptor.capture()); - renameRefactoringSessionCaptor.getValue().apply(session); - - verifyPreparingWizard(); - - verify(locale).renameMethodTitle(); - verify(view).setTitleCaption(nullable(String.class)); - verify(view).setVisibleKeepOriginalPanel(true); - - verify(view).showDialog(); - } - - @Test - public void renameLocalVariableWizardShouldBeShow() throws Exception { - - RefactorInfo refactorInfo = - RefactorInfo.of( - MoveType.REFACTOR_MENU, RefactoredItemType.COMPILATION_UNIT, new Resource[] {file}); - - renamePresenter.show(refactorInfo); - - verifyPreparingRenameRefactoringDto(); - - verify(refactorService).createRenameRefactoring(createRenameRefactoringDto); - verify(renameRefactoringSessionPromise).then(renameRefactoringSessionCaptor.capture()); - renameRefactoringSessionCaptor.getValue().apply(session); - - verifyPreparingWizard(); - - verify(locale).renameLocalVariableTitle(); - verify(view).setTitleCaption(nullable(String.class)); - - verify(view).showDialog(); - } - - @Test - public void renameLocalVariableWizardShouldBeShowedIfRefactoringInfoIsNull() throws Exception { - when(activeEditor.getCursorOffset()).thenReturn(2); - - renamePresenter.show((RefactorInfo) null); - - verify(createRenameRefactoringDto).setType(JAVA_ELEMENT); - verify(createRenameRefactoringDto).setPath(nullable(String.class)); - verify(createRenameRefactoringDto).setOffset(2); - - verify(refactorService).createRenameRefactoring(createRenameRefactoringDto); - verify(renameRefactoringSessionPromise).then(renameRefactoringSessionCaptor.capture()); - renameRefactoringSessionCaptor.getValue().apply(session); - - verifyPreparingWizard(); - - verify(locale).renameLocalVariableTitle(); - verify(view).setTitleCaption(nullable(String.class)); - - verify(view).showDialog(); - } - - @Test - public void renameProjectWizardShouldBeShowAsCompilationUnit() throws Exception { - refactorInfo = - RefactorInfo.of( - MoveType.REFACTOR_MENU, - RefactoredItemType.COMPILATION_UNIT, - new Resource[] {container}); - when(session.getWizardType()) - .thenReturn(RenameRefactoringSession.RenameWizard.COMPILATION_UNIT); - - renamePresenter.show(refactorInfo); - - verify(createRenameRefactoringDto).setType(PACKAGE); - verify(createRenameRefactoringDto).setPath("/project/src/a/b/c"); - - verify(refactorService).createRenameRefactoring(createRenameRefactoringDto); - verify(renameRefactoringSessionPromise).then(renameRefactoringSessionCaptor.capture()); - renameRefactoringSessionCaptor.getValue().apply(session); - - verifyPreparingWizard(); - - verify(locale).renameCompilationUnitTitle(); - verify(view).setTitleCaption(nullable(String.class)); - - verify(view).showDialog(); - } - - private void verifyPreparingWizard() { - verify(view).clearErrorLabel(); - verify(view).setOldName(TEXT); - verify(view).setEnableAcceptButton(false); - verify(view).setEnablePreviewButton(false); - verify(view).setVisiblePatternsPanel(false); - verify(view).setVisibleFullQualifiedNamePanel(false); - verify(view).setVisibleKeepOriginalPanel(false); - verify(view).setVisibleRenameSubpackagesPanel(false); - verify(view).setVisibleSimilarlyVariablesPanel(false); - } - - private void verifyPreparingRenameRefactoringDto() { - verify(createRenameRefactoringDto).setRefactorLightweight(false); - verify(createRenameRefactoringDto).setPath(nullable(String.class)); - verify(createRenameRefactoringDto).setType(COMPILATION_UNIT); - verify(createRenameRefactoringDto).setProjectPath(eq("/project")); - } - - @Test - public void changesShouldNotBeAppliedAndShowErrorMessage() throws Exception { - RefactoringStatus refactoringStatus = mock(RefactoringStatus.class); - when(refactoringStatus.getSeverity()).thenReturn(4); - when(changeCreationResult.isCanShowPreviewPage()).thenReturn(false); - when(changeCreationResult.getStatus()).thenReturn(refactoringStatus); - - renamePresenter.show(refactorInfo); - - verify(refactorService).createRenameRefactoring(createRenameRefactoringDto); - verify(renameRefactoringSessionPromise).then(renameRefactoringSessionCaptor.capture()); - renameRefactoringSessionCaptor.getValue().apply(session); - - renamePresenter.onAcceptButtonClicked(); - - verify(refactoringSession).setSessionId(SESSION_ID); - - verifyPreparingRenameSettingsDto(); - verifyPreparingRenameChanges(); - - verify(changeCreationResultPromise).then(changeCreationResultCaptor.capture()); - changeCreationResultCaptor.getValue().apply(changeCreationResult); - verify(view).showErrorMessage(any()); - } - - @Test - public void changesShouldNotBeAppliedAndShowNotificationMessage() throws Exception { - renamePresenter.show(refactorInfo); - - verify(refactorService).createRenameRefactoring(createRenameRefactoringDto); - verify(renameRefactoringSessionPromise).then(renameRefactoringSessionCaptor.capture()); - renameRefactoringSessionCaptor.getValue().apply(session); - - renamePresenter.onAcceptButtonClicked(); - - verify(refactoringSession).setSessionId(SESSION_ID); - - verifyPreparingRenameSettingsDto(); - verifyPreparingRenameChanges(); - - verify(changeCreationResultPromise).catchError(promiseErrorCaptor.capture()); - promiseErrorCaptor.getValue().apply(promiseError); - verify(promiseError).getMessage(); - verify(notificationManager) - .notify( - nullable(String.class), - nullable(String.class), - any(StatusNotification.Status.class), - any(DisplayMode.class)); - } - - @Test - public void changesShouldBeAppliedWithOkStatus() throws Exception { - RefactorInfo refactorInfo = - RefactorInfo.of( - MoveType.REFACTOR_MENU, RefactoredItemType.COMPILATION_UNIT, new Resource[] {file}); - - List changes = new ArrayList<>(); - when(refactoringStatus.getChanges()).thenReturn(changes); - - when(changeCreationResult.isCanShowPreviewPage()).thenReturn(true); - when(refactoringStatus.getSeverity()).thenReturn(0); - - renamePresenter.show(refactorInfo); - - verify(refactorService).createRenameRefactoring(createRenameRefactoringDto); - verify(renameRefactoringSessionPromise).then(renameRefactoringSessionCaptor.capture()); - renameRefactoringSessionCaptor.getValue().apply(session); - - renamePresenter.onAcceptButtonClicked(); - - verify(refactoringSession).setSessionId(SESSION_ID); - - verifyPreparingRenameSettingsDto(); - verifyPreparingRenameChanges(); - - verify(changeCreationResultPromise).then(changeCreationResultCaptor.capture()); - changeCreationResultCaptor.getValue().apply(changeCreationResult); - - verify(fileTrackingSuspendEventPromise).then(clientServerSuspendOperation.capture()); - clientServerSuspendOperation.getValue().apply(null); - - verify(refactorService).applyRefactoring(refactoringSession); - verify(refactoringStatusPromise).then(refactoringStatusCaptor.capture()); - refactoringStatusCaptor.getValue().apply(refactoringStatus); - - verify(refactoringStatus, times(2)).getSeverity(); - verify(view).close(); - - verify(updateAfterRefactoringPromise).then(updateAfterRefactoringOperation.capture()); - updateAfterRefactoringOperation.getValue().apply(null); - verify(refactoringUpdater) - .updateAfterRefactoring(org.mockito.ArgumentMatchers.>anyObject()); - verify(refactoringUpdater).handleMovingFiles(anyList()); - verify(clientServerEventService).sendFileTrackingResumeEvent(); - } - - @Test - public void changesShouldBeAppliedWithNotErrorStatus() throws Exception { - RefactorInfo refactorInfo = - RefactorInfo.of( - MoveType.REFACTOR_MENU, RefactoredItemType.COMPILATION_UNIT, new Resource[] {file}); - - when(changeCreationResult.isCanShowPreviewPage()).thenReturn(true); - when(refactoringStatus.getSeverity()).thenReturn(0); - - renamePresenter.show(refactorInfo); - - verify(refactorService).createRenameRefactoring(createRenameRefactoringDto); - verify(renameRefactoringSessionPromise).then(renameRefactoringSessionCaptor.capture()); - renameRefactoringSessionCaptor.getValue().apply(session); - - renamePresenter.onAcceptButtonClicked(); - - verify(refactoringSession).setSessionId(SESSION_ID); - - verifyPreparingRenameSettingsDto(); - verifyPreparingRenameChanges(); - - verify(changeCreationResultPromise).then(changeCreationResultCaptor.capture()); - changeCreationResultCaptor.getValue().apply(changeCreationResult); - - verify(fileTrackingSuspendEventPromise).then(clientServerSuspendOperation.capture()); - clientServerSuspendOperation.getValue().apply(null); - - verify(refactorService).applyRefactoring(refactoringSession); - verify(refactoringStatusPromise).then(refactoringStatusCaptor.capture()); - refactoringStatusCaptor.getValue().apply(refactoringStatus); - - verify(view).close(); - verify(updateAfterRefactoringPromise).then(updateAfterRefactoringOperation.capture()); - updateAfterRefactoringOperation.getValue().apply(null); - verify(refactoringUpdater) - .updateAfterRefactoring(org.mockito.ArgumentMatchers.>anyObject()); - verify(refactoringUpdater).handleMovingFiles(anyList()); - verify(clientServerEventService).sendFileTrackingResumeEvent(); - } - - @Test - public void previewPageIsNotReadyAndShowErrorMessage() throws Exception { - when(changeCreationResult.isCanShowPreviewPage()).thenReturn(false); - when(changeCreationResult.getStatus()).thenReturn(refactoringStatus); - when(refactoringStatus.getSeverity()).thenReturn(4); - - renamePresenter.show(refactorInfo); - - verify(refactorService).createRenameRefactoring(createRenameRefactoringDto); - verify(renameRefactoringSessionPromise).then(renameRefactoringSessionCaptor.capture()); - renameRefactoringSessionCaptor.getValue().apply(session); - - renamePresenter.onPreviewButtonClicked(); - - verify(refactoringSession).setSessionId(SESSION_ID); - - verifyPreparingRenameSettingsDto(); - verifyPreparingRenameChanges(); - - verify(changeCreationResultPromise).then(changeCreationResultCaptor.capture()); - changeCreationResultCaptor.getValue().apply(changeCreationResult); - verify(view).showErrorMessage(refactoringStatus); - } - - @Test - public void previewPageIsNotReadyAndShowNotificationMessage() throws Exception { - renamePresenter.show(refactorInfo); - - verify(refactorService).createRenameRefactoring(createRenameRefactoringDto); - verify(renameRefactoringSessionPromise).then(renameRefactoringSessionCaptor.capture()); - renameRefactoringSessionCaptor.getValue().apply(session); - - renamePresenter.onPreviewButtonClicked(); - - verify(refactoringSession).setSessionId(SESSION_ID); - - verifyPreparingRenameSettingsDto(); - verifyPreparingRenameChanges(); - - verify(changeCreationResultPromise).catchError(promiseErrorCaptor.capture()); - promiseErrorCaptor.getValue().apply(promiseError); - verify(promiseError).getMessage(); - verify(notificationManager) - .notify( - nullable(String.class), - nullable(String.class), - any(StatusNotification.Status.class), - any(DisplayMode.class)); - } - - @Test - public void previewPageShouldBeShow() throws Exception { - when(changeCreationResult.isCanShowPreviewPage()).thenReturn(true); - when(refactoringStatus.getSeverity()).thenReturn(0); - - renamePresenter.show(refactorInfo); - - verify(refactorService).createRenameRefactoring(createRenameRefactoringDto); - verify(renameRefactoringSessionPromise).then(renameRefactoringSessionCaptor.capture()); - renameRefactoringSessionCaptor.getValue().apply(session); - - renamePresenter.onPreviewButtonClicked(); - - verify(refactoringSession).setSessionId(SESSION_ID); - - verifyPreparingRenameSettingsDto(); - verifyPreparingRenameChanges(); - - verify(changeCreationResultPromise).then(changeCreationResultCaptor.capture()); - changeCreationResultCaptor.getValue().apply(changeCreationResult); - - verify(view).close(); - verify(previewPresenter).show(SESSION_ID, refactorInfo); - verify(previewPresenter).setTitle(nullable(String.class)); - } - - @Test - public void warningDialogShouldBeDisplayedWhenRefactoringPerformsWithWarning() - throws OperationException { - renamePresenter.show(session); - - ConfirmDialog dialog = mock(ConfirmDialog.class); - RefactoringStatusEntry statusEntry = mock(RefactoringStatusEntry.class); - List entries = Collections.singletonList(statusEntry); - - when(refactoringStatus.getEntries()).thenReturn(entries); - when(refactoringStatus.getSeverity()).thenReturn(2); - when(dialogFactory.createConfirmDialog( - nullable(String.class), - nullable(String.class), - nullable(String.class), - nullable(String.class), - org.mockito.ArgumentMatchers.anyObject(), - org.mockito.ArgumentMatchers.anyObject())) - .thenReturn(dialog); - renamePresenter.onAcceptButtonClicked(); - - verify(changeCreationResultPromise).then(changeCreationResultCaptor.capture()); - changeCreationResultCaptor.getValue().apply(changeCreationResult); - - verify(dialogFactory) - .createConfirmDialog( - nullable(String.class), - nullable(String.class), - nullable(String.class), - nullable(String.class), - org.mockito.ArgumentMatchers.anyObject(), - org.mockito.ArgumentMatchers.anyObject()); - verify(dialog).show(); - } - - @Test - public void previewPageShouldNotBeShow() throws Exception { - when(changeCreationResult.isCanShowPreviewPage()).thenReturn(false); - when(refactoringStatus.getSeverity()).thenReturn(4); - - renamePresenter.show(refactorInfo); - - verify(refactorService).createRenameRefactoring(createRenameRefactoringDto); - verify(renameRefactoringSessionPromise).then(renameRefactoringSessionCaptor.capture()); - renameRefactoringSessionCaptor.getValue().apply(session); - - renamePresenter.onPreviewButtonClicked(); - - verify(refactoringSession).setSessionId(SESSION_ID); - - verifyPreparingRenameSettingsDto(); - verifyPreparingRenameChanges(); - - verify(changeCreationResultPromise).then(changeCreationResultCaptor.capture()); - changeCreationResultCaptor.getValue().apply(changeCreationResult); - - verify(view).showErrorMessage(any()); - } - - @Test - public void focusShouldBeSetAfterClosingTheEditor() throws Exception { - renamePresenter.onCancelButtonClicked(); - - verify(activeEditor).setFocus(); - } - - private void verifyPreparingRenameSettingsDto() { - verify(renameSettings).setDelegateUpdating(true); - verify(view, times(2)).isUpdateDelegateUpdating(); - verify(renameSettings).setUpdateSubpackages(anyBoolean()); - verify(view).isUpdateSubpackages(); - verify(renameSettings).setUpdateReferences(anyBoolean()); - verify(view).isUpdateReferences(); - verify(renameSettings).setUpdateQualifiedNames(true); - verify(view, times(2)).isUpdateQualifiedNames(); - verify(renameSettings).setFilePatterns(nullable(String.class)); - verify(renameSettings).setUpdateTextualMatches(anyBoolean()); - verify(view).isUpdateTextualOccurrences(); - verify(renameSettings).setUpdateSimilarDeclarations(true); - verify(view, times(2)).isUpdateSimilarlyVariables(); - verify(renameSettings).setMachStrategy(3); - verify(similarNamesConfigurationPresenter).getMachStrategy(); - } - - private void verifyPreparingRenameChanges() throws FunctionException { - verify(refactorService).setRenameSettings(renameSettings); - verify(renameSettingsPromise).thenPromise(renameSettingsPromiseCaptor.capture()); - renameSettingsPromiseCaptor.getValue().apply(any()); - verify(refactorService).createChange(refactoringSession); - } -} diff --git a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/test/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/similarnames/SimilarNamesConfigurationPresenterTest.java b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/test/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/similarnames/SimilarNamesConfigurationPresenterTest.java index f21e78377018..be12d159f62d 100644 --- a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/test/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/similarnames/SimilarNamesConfigurationPresenterTest.java +++ b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/test/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/similarnames/SimilarNamesConfigurationPresenterTest.java @@ -38,8 +38,8 @@ public void windowShouldBeShow() throws Exception { @Test public void valueOfStrategyShouldBeReturned() throws Exception { - presenter.getMachStrategy(); + presenter.getMatchStrategy(); - verify(view).getMachStrategy(); + verify(view).getMatchStrategy(); } } diff --git a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/test/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/similarnames/SimilarNamesConfigurationViewImplTest.java b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/test/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/similarnames/SimilarNamesConfigurationViewImplTest.java index 7d858f22d935..31e450057468 100644 --- a/plugins/plugin-java/che-plugin-java-ext-lang-client/src/test/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/similarnames/SimilarNamesConfigurationViewImplTest.java +++ b/plugins/plugin-java/che-plugin-java-ext-lang-client/src/test/java/org/eclipse/che/ide/ext/java/client/refactoring/rename/wizard/similarnames/SimilarNamesConfigurationViewImplTest.java @@ -39,7 +39,7 @@ public void machStrategyShouldBeReturnExacValue() throws Exception { when(view.findExactNames.getValue()).thenReturn(true); verify(locale).renameSimilarNamesConfigurationTitle(); - assertEquals(RenameSettings.MachStrategy.EXACT, view.getMachStrategy()); + assertEquals(RenameSettings.MachStrategy.EXACT, view.getMatchStrategy()); } @Test @@ -47,7 +47,7 @@ public void machStrategyShouldBeReturnEmbeddedValue() throws Exception { when(view.findExactNames.getValue()).thenReturn(false); when(view.findEmbeddedNames.getValue()).thenReturn(true); - assertEquals(RenameSettings.MachStrategy.EMBEDDED, view.getMachStrategy()); + assertEquals(RenameSettings.MachStrategy.EMBEDDED, view.getMatchStrategy()); } @Test @@ -56,6 +56,6 @@ public void machStrategyShouldBeReturnSuffixValue() throws Exception { when(view.findEmbeddedNames.getValue()).thenReturn(false); when(view.findNameSuffixes.getValue()).thenReturn(true); - assertEquals(RenameSettings.MachStrategy.SUFFIX, view.getMachStrategy()); + assertEquals(RenameSettings.MachStrategy.SUFFIX, view.getMatchStrategy()); } } diff --git a/plugins/plugin-java/che-plugin-java-ext-lang-shared/src/main/java/org/eclipse/che/ide/ext/java/shared/Constants.java b/plugins/plugin-java/che-plugin-java-ext-lang-shared/src/main/java/org/eclipse/che/ide/ext/java/shared/Constants.java index 675bc2333496..a31f1bb01d40 100644 --- a/plugins/plugin-java/che-plugin-java-ext-lang-shared/src/main/java/org/eclipse/che/ide/ext/java/shared/Constants.java +++ b/plugins/plugin-java/che-plugin-java-ext-lang-shared/src/main/java/org/eclipse/che/ide/ext/java/shared/Constants.java @@ -56,6 +56,11 @@ public final class Constants { public static final String PROGRESS_OUTPUT_UNSUBSCRIBE = "progressOutput/unsubscribe"; public static final String PROGRESS_OUTPUT_SUBSCRIBE = "progressOutput/subscribe"; + public static final String REFACTORING_RENAME = "java/refactoringRename"; + public static final String REFACTORING_GET_RENAME_TYPE = "java/refactoringGetRenameType"; + public static final String VALIDATE_RENAMED_NAME = "java/validateRenamedName"; + public static final String GET_LINKED_MODEL = "java/getLinkedModel"; + private Constants() { throw new UnsupportedOperationException("Unused constructor."); } diff --git a/plugins/plugin-java/che-plugin-java-server/pom.xml b/plugins/plugin-java/che-plugin-java-server/pom.xml index 8b32101939c1..9cd6997278e1 100644 --- a/plugins/plugin-java/che-plugin-java-server/pom.xml +++ b/plugins/plugin-java/che-plugin-java-server/pom.xml @@ -154,9 +154,13 @@ org.eclipse.lsp4j.Position org.eclipse.lsp4j.WorkspaceEdit org.eclipse.lsp4j.ResourceChange + org.eclipse.lsp4j.RenameParams + org.eclipse.lsp4j.TextDocumentIdentifier org.eclipse.lsp4j.TextEdit org.eclipse.lsp4j.TextDocumentEdit org.eclipse.lsp4j.VersionedTextDocumentIdentifier + org.eclipse.che.jdt.ls.extension.api.dto.CheResourceChange + org.eclipse.che.jdt.ls.extension.api.dto.CheWorkspaceEdit org.eclipse.che.jdt.ls.extension.api.dto diff --git a/plugins/plugin-java/che-plugin-java-server/src/main/java/org/eclipse/che/plugin/java/languageserver/JavaLSWrapper.java b/plugins/plugin-java/che-plugin-java-server/src/main/java/org/eclipse/che/plugin/java/languageserver/JavaLSWrapper.java index ccc87434a94d..1d78f64794f0 100644 --- a/plugins/plugin-java/che-plugin-java-server/src/main/java/org/eclipse/che/plugin/java/languageserver/JavaLSWrapper.java +++ b/plugins/plugin-java/che-plugin-java-server/src/main/java/org/eclipse/che/plugin/java/languageserver/JavaLSWrapper.java @@ -18,6 +18,8 @@ import org.eclipse.che.api.languageserver.util.DynamicWrapper; import org.eclipse.lsp4j.InitializeParams; import org.eclipse.lsp4j.InitializeResult; +import org.eclipse.lsp4j.WorkspaceClientCapabilities; +import org.eclipse.lsp4j.WorkspaceEditCapabilities; import org.eclipse.lsp4j.services.TextDocumentService; public class JavaLSWrapper { @@ -37,6 +39,13 @@ public CompletableFuture initialize(InitializeParams params) { extendedCapabilities.put("progressReportProvider", "true"); extendedCapabilities.put("classFileContentsSupport", "true"); initOptions.put("extendedClientCapabilities", extendedCapabilities); + + WorkspaceClientCapabilities workspaceClientCapabilities = + params.getCapabilities().getWorkspace(); + WorkspaceEditCapabilities workspaceEditCapabilities = new WorkspaceEditCapabilities(); + workspaceEditCapabilities.setResourceChanges(true); + workspaceClientCapabilities.setWorkspaceEdit(workspaceEditCapabilities); + Map settings = new HashMap<>(); settings.put("java.configuration.updateBuildConfiguration", "automatic"); initOptions.put("settings", settings); @@ -47,6 +56,7 @@ public CompletableFuture initialize(InitializeParams params) { result -> { result.getCapabilities().setDocumentSymbolProvider(false); result.getCapabilities().setReferencesProvider(false); + result.getCapabilities().setRenameProvider(false); return result; }); } diff --git a/plugins/plugin-java/che-plugin-java-server/src/main/java/org/eclipse/che/plugin/java/languageserver/JavaLanguageServerExtensionService.java b/plugins/plugin-java/che-plugin-java-server/src/main/java/org/eclipse/che/plugin/java/languageserver/JavaLanguageServerExtensionService.java index 0a0dd9c5cbf4..a744fbd2e4c0 100644 --- a/plugins/plugin-java/che-plugin-java-server/src/main/java/org/eclipse/che/plugin/java/languageserver/JavaLanguageServerExtensionService.java +++ b/plugins/plugin-java/che-plugin-java-server/src/main/java/org/eclipse/che/plugin/java/languageserver/JavaLanguageServerExtensionService.java @@ -24,13 +24,17 @@ import static org.eclipse.che.ide.ext.java.shared.Constants.EXTERNAL_LIBRARY_ENTRY; import static org.eclipse.che.ide.ext.java.shared.Constants.FILE_STRUCTURE; import static org.eclipse.che.ide.ext.java.shared.Constants.GET_JAVA_CORE_OPTIONS; +import static org.eclipse.che.ide.ext.java.shared.Constants.GET_LINKED_MODEL; import static org.eclipse.che.ide.ext.java.shared.Constants.IMPLEMENTERS; import static org.eclipse.che.ide.ext.java.shared.Constants.ORGANIZE_IMPORTS; import static org.eclipse.che.ide.ext.java.shared.Constants.RECOMPUTE_POM_DIAGNOSTICS; +import static org.eclipse.che.ide.ext.java.shared.Constants.REFACTORING_GET_RENAME_TYPE; +import static org.eclipse.che.ide.ext.java.shared.Constants.REFACTORING_RENAME; import static org.eclipse.che.ide.ext.java.shared.Constants.REIMPORT_MAVEN_PROJECTS; import static org.eclipse.che.ide.ext.java.shared.Constants.REIMPORT_MAVEN_PROJECTS_REQUEST_TIMEOUT; import static org.eclipse.che.ide.ext.java.shared.Constants.UPDATE_JAVA_CORE_OPTIONS; import static org.eclipse.che.ide.ext.java.shared.Constants.USAGES; +import static org.eclipse.che.ide.ext.java.shared.Constants.VALIDATE_RENAMED_NAME; import static org.eclipse.che.jdt.ls.extension.api.Commands.CREATE_SIMPLE_PROJECT; import static org.eclipse.che.jdt.ls.extension.api.Commands.FILE_STRUCTURE_COMMAND; import static org.eclipse.che.jdt.ls.extension.api.Commands.FIND_IMPLEMENTERS_COMMAND; @@ -48,6 +52,7 @@ import static org.eclipse.che.jdt.ls.extension.api.Commands.GET_OUTPUT_DIR_COMMAND; import static org.eclipse.che.jdt.ls.extension.api.Commands.GET_SOURCE_FOLDERS; import static org.eclipse.che.jdt.ls.extension.api.Commands.REIMPORT_MAVEN_PROJECTS_COMMAND; +import static org.eclipse.che.jdt.ls.extension.api.Commands.RENAME_COMMAND; import static org.eclipse.che.jdt.ls.extension.api.Commands.RESOLVE_CLASSPATH_COMMAND; import static org.eclipse.che.jdt.ls.extension.api.Commands.TEST_DETECT_COMMAND; import static org.eclipse.che.jdt.ls.extension.api.Commands.UPDATE_PROJECT_CLASSPATH; @@ -62,8 +67,10 @@ import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Arrays; +import java.util.LinkedHashMap; import java.util.List; import java.util.ListIterator; +import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -86,6 +93,8 @@ import org.eclipse.che.api.project.server.notification.ProjectUpdatedEvent; import org.eclipse.che.jdt.ls.extension.api.Commands; import org.eclipse.che.jdt.ls.extension.api.Severity; +import org.eclipse.che.jdt.ls.extension.api.dto.CheResourceChange; +import org.eclipse.che.jdt.ls.extension.api.dto.CheWorkspaceEdit; import org.eclipse.che.jdt.ls.extension.api.dto.ClasspathEntry; import org.eclipse.che.jdt.ls.extension.api.dto.ExtendedSymbolInformation; import org.eclipse.che.jdt.ls.extension.api.dto.ExternalLibrariesParameters; @@ -95,9 +104,13 @@ import org.eclipse.che.jdt.ls.extension.api.dto.JarEntry; import org.eclipse.che.jdt.ls.extension.api.dto.JavaCoreOptions; import org.eclipse.che.jdt.ls.extension.api.dto.JobResult; +import org.eclipse.che.jdt.ls.extension.api.dto.NameValidationStatus; import org.eclipse.che.jdt.ls.extension.api.dto.OrganizeImportParams; import org.eclipse.che.jdt.ls.extension.api.dto.OrganizeImportsResult; import org.eclipse.che.jdt.ls.extension.api.dto.ReImportMavenProjectsCommandParameters; +import org.eclipse.che.jdt.ls.extension.api.dto.RenameSelectionParams; +import org.eclipse.che.jdt.ls.extension.api.dto.RenameSettings; +import org.eclipse.che.jdt.ls.extension.api.dto.RenamingElementInfo; import org.eclipse.che.jdt.ls.extension.api.dto.ResourceLocation; import org.eclipse.che.jdt.ls.extension.api.dto.TestFindParameters; import org.eclipse.che.jdt.ls.extension.api.dto.TestPosition; @@ -111,9 +124,11 @@ import org.eclipse.che.plugin.java.languageserver.dto.DtoServerImpls.ImplementersResponseDto; import org.eclipse.che.plugin.java.languageserver.dto.DtoServerImpls.TestPositionDto; import org.eclipse.lsp4j.ExecuteCommandParams; +import org.eclipse.lsp4j.Range; import org.eclipse.lsp4j.ServerCapabilities; import org.eclipse.lsp4j.SymbolInformation; import org.eclipse.lsp4j.TextDocumentPositionParams; +import org.eclipse.lsp4j.TextEdit; import org.eclipse.lsp4j.jsonrpc.json.adapters.CollectionTypeAdapterFactory; import org.eclipse.lsp4j.jsonrpc.json.adapters.EitherTypeAdapterFactory; import org.eclipse.lsp4j.jsonrpc.json.adapters.EnumTypeAdapterFactory; @@ -258,6 +273,34 @@ public void configureMethods() { .paramsAsDto(JavaCoreOptions.class) .resultAsBoolean() .withFunction(this::updateJavaCoreOptions); + + requestHandler + .newConfiguration() + .methodName(REFACTORING_RENAME) + .paramsAsDto(RenameSettings.class) + .resultAsDto(CheWorkspaceEdit.class) + .withFunction(this::rename); + + requestHandler + .newConfiguration() + .methodName(REFACTORING_GET_RENAME_TYPE) + .paramsAsDto(RenameSelectionParams.class) + .resultAsDto(RenamingElementInfo.class) + .withFunction(this::getRenamingElementInfo); + + requestHandler + .newConfiguration() + .methodName(VALIDATE_RENAMED_NAME) + .paramsAsDto(RenameSelectionParams.class) + .resultAsDto(NameValidationStatus.class) + .withFunction(this::validateName); + + requestHandler + .newConfiguration() + .methodName(GET_LINKED_MODEL) + .paramsAsDto(TextDocumentPositionParams.class) + .resultAsListOfDto(Range.class) + .withFunction(this::getLinkedElements); } /** @@ -600,6 +643,72 @@ private JarEntry getLibraryEntry(String resourceUri) { return doGetOne(GET_LIBRARY_ENTRY_COMMAND, singletonList(fixJdtUri(resourceUri)), type); } + private CheWorkspaceEdit rename(RenameSettings renameSettings) { + Type type = new TypeToken() {}.getType(); + String uri = renameSettings.getRenameParams().getTextDocument().getUri(); + renameSettings.getRenameParams().getTextDocument().setUri(prefixURI(uri)); + + CheWorkspaceEdit cheWorkspaceEdit = + doGetOne(RENAME_COMMAND, singletonList(renameSettings), type); + List resourceChanges = getResourceChanges(cheWorkspaceEdit); + cheWorkspaceEdit.setCheResourceChanges(resourceChanges); + cheWorkspaceEdit.setChanges(getTextChanges(cheWorkspaceEdit)); + return cheWorkspaceEdit; + } + + private List getResourceChanges(CheWorkspaceEdit cheWorkspaceEdit) { + return cheWorkspaceEdit + .getCheResourceChanges() + .stream() + .peek( + each -> { + String current = each.getCurrent(); + String newUri = each.getNewUri(); + if (current != null) { + each.setCurrent(LanguageServiceUtils.removePrefixUri(current)); + } + if (newUri != null) { + each.setNewUri(LanguageServiceUtils.removePrefixUri(newUri)); + } + }) + .collect(Collectors.toList()); + } + + private Map> getTextChanges(CheWorkspaceEdit cheWorkspaceEdit) { + Map> changes = new LinkedHashMap<>(); + for (String uri : cheWorkspaceEdit.getChanges().keySet()) { + changes.put( + LanguageServiceUtils.removePrefixUri(uri), cheWorkspaceEdit.getChanges().get(uri)); + } + return changes; + } + + private RenamingElementInfo getRenamingElementInfo(RenameSelectionParams renameSelection) { + Type type = new TypeToken() {}.getType(); + String uri = renameSelection.getResourceUri(); + renameSelection.setResourceUri(prefixURI(uri)); + + return doGetOne(Commands.GET_RENAME_TYPE_COMMAND, singletonList(renameSelection), type); + } + + private NameValidationStatus validateName(RenameSelectionParams renameSelectionParams) { + Type type = new TypeToken() {}.getType(); + String uri = renameSelectionParams.getResourceUri(); + renameSelectionParams.setResourceUri(prefixURI(uri)); + + return doGetOne( + Commands.VALIDATE_RENAMED_NAME_COMMAND, singletonList(renameSelectionParams), type); + } + + private List getLinkedElements(TextDocumentPositionParams textDocumentPositionParams) { + Type type = new TypeToken>() {}.getType(); + String uri = textDocumentPositionParams.getTextDocument().getUri(); + textDocumentPositionParams.getTextDocument().setUri(prefixURI(uri)); + + return doGetOne( + Commands.GET_LINKED_ELEMENTS_COMMAND, singletonList(textDocumentPositionParams), type); + } + private List executeFindTestsCommand( String commandId, String fileUri, diff --git a/plugins/plugin-languageserver/che-plugin-languageserver-ide/src/main/java/org/eclipse/che/plugin/languageserver/ide/editor/quickassist/ApplyWorkspaceEditAction.java b/plugins/plugin-languageserver/che-plugin-languageserver-ide/src/main/java/org/eclipse/che/plugin/languageserver/ide/editor/quickassist/ApplyWorkspaceEditAction.java index a16d62062b31..056ea8578420 100644 --- a/plugins/plugin-languageserver/che-plugin-languageserver-ide/src/main/java/org/eclipse/che/plugin/languageserver/ide/editor/quickassist/ApplyWorkspaceEditAction.java +++ b/plugins/plugin-languageserver/che-plugin-languageserver-ide/src/main/java/org/eclipse/che/plugin/languageserver/ide/editor/quickassist/ApplyWorkspaceEditAction.java @@ -10,7 +10,12 @@ */ package org.eclipse.che.plugin.languageserver.ide.editor.quickassist; +import static com.google.common.base.Strings.isNullOrEmpty; + +import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.inject.Inject; +import com.google.web.bindery.event.shared.EventBus; +import elemental.util.ArrayOf; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -22,18 +27,17 @@ import org.eclipse.che.api.languageserver.shared.dto.DtoClientImpls.FileEditParamsDto; import org.eclipse.che.api.languageserver.shared.model.FileEditParams; import org.eclipse.che.api.languageserver.shared.util.RangeComparator; -import org.eclipse.che.api.promises.client.Function; -import org.eclipse.che.api.promises.client.Promise; -import org.eclipse.che.api.promises.client.PromiseError; -import org.eclipse.che.api.promises.client.PromiseProvider; +import org.eclipse.che.api.promises.client.*; import org.eclipse.che.api.promises.client.js.Executor; import org.eclipse.che.api.promises.client.js.RejectFunction; import org.eclipse.che.api.promises.client.js.ResolveFunction; import org.eclipse.che.ide.api.action.ActionEvent; import org.eclipse.che.ide.api.action.BaseAction; +import org.eclipse.che.ide.api.app.AppContext; import org.eclipse.che.ide.api.editor.EditorAgent; import org.eclipse.che.ide.api.editor.EditorPartPresenter; import org.eclipse.che.ide.api.editor.document.Document; +import org.eclipse.che.ide.api.editor.events.FileEvent; import org.eclipse.che.ide.api.editor.texteditor.HandlesUndoRedo; import org.eclipse.che.ide.api.editor.texteditor.TextEditor; import org.eclipse.che.ide.api.notification.Notification; @@ -41,14 +45,26 @@ import org.eclipse.che.ide.api.notification.StatusNotification; import org.eclipse.che.ide.api.notification.StatusNotification.DisplayMode; import org.eclipse.che.ide.api.notification.StatusNotification.Status; +import org.eclipse.che.ide.api.resources.Container; +import org.eclipse.che.ide.api.resources.Resource; +import org.eclipse.che.ide.api.resources.VirtualFile; import org.eclipse.che.ide.dto.DtoFactory; +import org.eclipse.che.ide.project.ProjectServiceClient; +import org.eclipse.che.ide.resource.Path; import org.eclipse.che.ide.util.loging.Log; +import org.eclipse.che.jdt.ls.extension.api.ResourceKind; +import org.eclipse.che.jdt.ls.extension.api.dto.CheResourceChange; +import org.eclipse.che.jdt.ls.extension.api.dto.CheWorkspaceEdit; import org.eclipse.che.plugin.languageserver.ide.LanguageServerLocalization; +import org.eclipse.che.plugin.languageserver.ide.service.TextDocumentServiceClient; import org.eclipse.che.plugin.languageserver.ide.service.WorkspaceServiceClient; +import org.eclipse.che.plugin.languageserver.ide.util.DtoBuildHelper; import org.eclipse.che.plugin.languageserver.ide.util.PromiseHelper; +import org.eclipse.lsp4j.DidCloseTextDocumentParams; import org.eclipse.lsp4j.Position; import org.eclipse.lsp4j.Range; import org.eclipse.lsp4j.TextDocumentEdit; +import org.eclipse.lsp4j.TextDocumentIdentifier; import org.eclipse.lsp4j.TextEdit; import org.eclipse.lsp4j.WorkspaceEdit; @@ -59,8 +75,14 @@ public class ApplyWorkspaceEditAction extends BaseAction { private EditorAgent editorAgent; private DtoFactory dtoFactory; + private DtoBuildHelper dtoHelper; + private AppContext appContext; private WorkspaceServiceClient workspaceService; + private ProjectServiceClient projectService; + private EventBus eventBus; private PromiseHelper promiseHelper; + private PromiseProvider promises; + private TextDocumentServiceClient textDocumentService; private LanguageServerLocalization localization; private NotificationManager notificationManager; private PromiseProvider promiseProvider; @@ -69,15 +91,27 @@ public class ApplyWorkspaceEditAction extends BaseAction { public ApplyWorkspaceEditAction( EditorAgent editorAgent, DtoFactory dtoFactory, + DtoBuildHelper dtoHelper, + AppContext appContext, WorkspaceServiceClient workspaceService, + ProjectServiceClient projectService, + EventBus eventBus, PromiseHelper promiseHelper, + PromiseProvider promises, + TextDocumentServiceClient textDocumentService, LanguageServerLocalization localization, NotificationManager notificationManager, PromiseProvider promiseProvider) { this.editorAgent = editorAgent; this.dtoFactory = dtoFactory; + this.dtoHelper = dtoHelper; + this.appContext = appContext; this.workspaceService = workspaceService; + this.projectService = projectService; + this.eventBus = eventBus; this.promiseHelper = promiseHelper; + this.promises = promises; + this.textDocumentService = textDocumentService; this.localization = localization; this.notificationManager = notificationManager; this.promiseProvider = promiseProvider; @@ -121,10 +155,21 @@ public void applyWorkspaceEdit(WorkspaceEdit edit) { undos::add); done.then( - (Void v) -> { - Log.debug(getClass(), "done applying changes"); - notification.setStatus(Status.SUCCESS); - notification.setContent(localization.applyWorkspaceActionNotificationDone()); + v -> { + if (edit instanceof CheWorkspaceEdit) { + applyResourceChanges(notification, (CheWorkspaceEdit) edit) + .then( + ignored -> { + Log.debug(getClass(), "done applying changes"); + notification.setStatus(Status.SUCCESS); + notification.setContent( + localization.applyWorkspaceActionNotificationDone()); + }); + } else { + Log.debug(getClass(), "done applying changes"); + notification.setStatus(Status.SUCCESS); + notification.setContent(localization.applyWorkspaceActionNotificationDone()); + } }) .catchError( (error) -> { @@ -147,6 +192,132 @@ public void applyWorkspaceEdit(WorkspaceEdit edit) { }); } + private Promise applyResourceChanges(Notification notification, CheWorkspaceEdit edit) { + List resourceChanges = edit.getCheResourceChanges(); + if (resourceChanges.isEmpty()) { + return promises.resolve(null); + } + + ArrayOf> changesPromises = elemental.util.Collections.arrayOf(); + + for (CheResourceChange change : resourceChanges) { + if (change == null) { + continue; + } + String newUri = change.getNewUri(); + String current = change.getCurrent(); + + Path path = Path.valueOf(newUri).makeAbsolute(); + if (isNullOrEmpty(current)) { + createResource(path, change.getResourceKind(), notification); + continue; + } + Path oldPath = Path.valueOf(current).makeAbsolute(); + + Container workspaceRoot = appContext.getWorkspaceRoot(); + changesPromises.push( + workspaceRoot + .getResource(oldPath) + .then( + resourceOptional -> { + if (!resourceOptional.isPresent()) { + return; + } + + Resource resource = resourceOptional.get(); + + editorAgent.saveAll( + new AsyncCallback() { + @Override + public void onFailure(Throwable throwable) { + notification.setContent("Can't save files."); + } + + @Override + public void onSuccess(Void aVoid) { + final List openedEditors = + editorAgent.getOpenedEditors(); + for (EditorPartPresenter editor : openedEditors) { + if (resource + .getLocation() + .isPrefixOf(editor.getEditorInput().getFile().getLocation())) { + TextDocumentIdentifier documentId = + dtoHelper.createTDI(editor.getEditorInput().getFile()); + DidCloseTextDocumentParams closeEvent = + dtoFactory.createDto(DidCloseTextDocumentParams.class); + closeEvent.setTextDocument(documentId); + textDocumentService.didClose(closeEvent); + } + } + moveResource(resource, path, notification); + } + }); + })); + } + return promises.all2(changesPromises).thenPromise(ignored -> promises.resolve(null)); + } + + private void createResource(Path path, ResourceKind kind, Notification notification) { + Container workspaceRoot = appContext.getWorkspaceRoot(); + workspaceRoot + .getResource(path) + .then( + resource -> { + if (ResourceKind.FOLDER.equals(kind)) { + projectService + .createFolder(path) + .catchError( + error -> { + notification.setContent(error.getMessage()); + }); + } else if (ResourceKind.FILE.equals(kind)) { + projectService + .createFile(path, "") + .catchError( + error -> { + notification.setContent(error.getMessage()); + }); + } + }); + } + + private void moveResource(Resource resource, Path path, Notification notification) { + if (resource.isProject()) { + closeRelatedEditors(resource); + } + resource + .move(path) + .then( + movedResource -> { + if (movedResource.isFolder()) { + return; + } + final List openedEditors = editorAgent.getOpenedEditors(); + + for (EditorPartPresenter editor : openedEditors) { + VirtualFile file = editor.getEditorInput().getFile(); + if (movedResource.getLocation().equals(file.getLocation())) { + eventBus.fireEvent(FileEvent.createFileOpenedEvent(file)); + return; + } + } + }) + .catchError( + arg -> { + notification.setContent(arg.getMessage()); + }); + } + + private void closeRelatedEditors(Resource resource) { + final List openedEditors = editorAgent.getOpenedEditors(); + + for (EditorPartPresenter editor : openedEditors) { + if (resource.getLocation().isPrefixOf(editor.getEditorInput().getFile().getLocation())) { + editorAgent.closeEditor(editor); + } + } + } + private Promise>> handleFileChange( Notification notification, String uri, List edits) { for (EditorPartPresenter editor : editorAgent.getOpenedEditors()) {