From f63b13da104fa01d101b36940cd3a55a6e69f60f Mon Sep 17 00:00:00 2001 From: Vladyslav Zhukovskii Date: Wed, 16 Nov 2016 15:04:38 +0200 Subject: [PATCH 1/6] Add hotkey for expand/collapse project tree --- .../che/ide/api/data/tree/TreeExpander.java | 47 ++++++++++ .../che/ide/actions/common/ActionFactory.java | 65 +++++++++++++ .../actions/common/TreeCollapseAction.java | 53 +++++++++++ .../ide/actions/common/TreeExpandAction.java | 53 +++++++++++ .../project/ProjectExplorerPresenter.java | 92 ++++++++++++++++++- .../ide/resources/impl/ResourceManager.java | 4 +- .../eclipse/che/ide/ui/smartTree/Tree.java | 4 + 7 files changed, 315 insertions(+), 3 deletions(-) create mode 100644 ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/data/tree/TreeExpander.java create mode 100644 ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/ActionFactory.java create mode 100644 ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/TreeCollapseAction.java create mode 100644 ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/TreeExpandAction.java diff --git a/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/data/tree/TreeExpander.java b/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/data/tree/TreeExpander.java new file mode 100644 index 00000000000..c12df8dfeb4 --- /dev/null +++ b/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/data/tree/TreeExpander.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2012-2016 Codenvy, S.A. + * 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: + * Codenvy, S.A. - initial API and implementation + *******************************************************************************/ +package org.eclipse.che.ide.api.data.tree; + +import com.google.common.annotations.Beta; + +/** + * Component which performs basic tree operation such as expand and collapse. + * + * @author Vlad Zhukovskyi + * @since 5.0.0 + */ +@Beta +public interface TreeExpander { + + /** + * Perform tree expand in case if {@link #isExpandEnabled()} returns {@code true}. + */ + void expandTree(); + + /** + * Returns {@code true} in case if tree expand is possible. + * + * @return {@code true} in case if tree expand is possible, otherwise {@code false} + */ + boolean isExpandEnabled(); + + /** + * Perform tree collapse in case if {@link #isCollapseEnabled()} returns {@code true}. + */ + void collapseTree(); + + /** + * Returns {@code true} in case if tree collapse is possible. + * + * @return {@code true} in case if tree collapse is possible, otherwise {@code false} + */ + boolean isCollapseEnabled(); +} diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/ActionFactory.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/ActionFactory.java new file mode 100644 index 00000000000..23e60354041 --- /dev/null +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/ActionFactory.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2012-2016 Codenvy, S.A. + * 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: + * Codenvy, S.A. - initial API and implementation + *******************************************************************************/ +package org.eclipse.che.ide.actions.common; + +import com.google.common.annotations.Beta; + +import org.eclipse.che.ide.api.action.Action; +import org.eclipse.che.ide.api.data.tree.TreeExpander; + +/** + * Utility methods to create basic common actions. + * + * @author Vlad Zhukovskyi + * @since 5.0.0 + */ +@Beta +public class ActionFactory { + + /** + * Returns the instance of the {@link TreeExpandAction} based on the given {@code expander}. + * + * @param expander + * tree expander + * @return instance of the {@link TreeExpandAction} + * @see TreeExpandAction + * @see TreeExpander + * @since 5.0.0 + */ + public Action createExpandTreeAction(final TreeExpander expander) { + return new TreeExpandAction() { + @Override + public TreeExpander getTreeExpander() { + return expander; + } + }; + } + + /** + * Returns the instance of the {@link TreeCollapseAction} based on the given {@code expander}. + * + * @param expander + * tree expander + * @return instance of the {@link TreeCollapseAction} + * @see TreeCollapseAction + * @see TreeExpander + * @since 5.0.0 + */ + public Action createCollapseTreeAction(final TreeExpander expander) { + return new TreeCollapseAction() { + @Override + public TreeExpander getTreeExpander() { + return expander; + } + }; + } + +} diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/TreeCollapseAction.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/TreeCollapseAction.java new file mode 100644 index 00000000000..aeaf671c5a8 --- /dev/null +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/TreeCollapseAction.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2012-2016 Codenvy, S.A. + * 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: + * Codenvy, S.A. - initial API and implementation + *******************************************************************************/ +package org.eclipse.che.ide.actions.common; + +import org.eclipse.che.ide.api.action.Action; +import org.eclipse.che.ide.api.action.ActionEvent; +import org.eclipse.che.ide.api.data.tree.TreeExpander; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Base tree collapse action which consumes instance of {@link TreeExpander}. + * + * @author Vlad Zhukovskyi + * @see TreeExpander + * @since 5.0.0 + */ +public abstract class TreeCollapseAction extends Action { + + public abstract TreeExpander getTreeExpander(); + + public TreeCollapseAction() { + super("Collapse All"); + } + + @Override + public void actionPerformed(ActionEvent e) { + final TreeExpander treeExpander = getTreeExpander(); + + checkNotNull(treeExpander); + + if (!treeExpander.isCollapseEnabled()) { + return; + } + + treeExpander.collapseTree(); + } + + @Override + public void update(ActionEvent e) { + final TreeExpander treeExpander = getTreeExpander(); + + e.getPresentation().setEnabledAndVisible(treeExpander.isCollapseEnabled()); + } +} diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/TreeExpandAction.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/TreeExpandAction.java new file mode 100644 index 00000000000..0a443eee4d3 --- /dev/null +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/TreeExpandAction.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2012-2016 Codenvy, S.A. + * 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: + * Codenvy, S.A. - initial API and implementation + *******************************************************************************/ +package org.eclipse.che.ide.actions.common; + +import org.eclipse.che.ide.api.action.Action; +import org.eclipse.che.ide.api.action.ActionEvent; +import org.eclipse.che.ide.api.data.tree.TreeExpander; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Base tree expand action which consumes instance of {@link TreeExpander}. + * + * @author Vlad Zhukovskyi + * @see TreeExpander + * @since 5.0.0 + */ +public abstract class TreeExpandAction extends Action { + + public abstract TreeExpander getTreeExpander(); + + public TreeExpandAction() { + super("Expand All"); + } + + @Override + public void actionPerformed(ActionEvent e) { + final TreeExpander treeExpander = getTreeExpander(); + + checkNotNull(treeExpander); + + if (!treeExpander.isExpandEnabled()) { + return; + } + + treeExpander.expandTree(); + } + + @Override + public void update(ActionEvent e) { + final TreeExpander treeExpander = getTreeExpander(); + + e.getPresentation().setEnabledAndVisible(treeExpander.isExpandEnabled()); + } +} diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerPresenter.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerPresenter.java index ab8006059cf..db80fc6b7ca 100644 --- a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerPresenter.java +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerPresenter.java @@ -11,18 +11,28 @@ package org.eclipse.che.ide.part.explorer.project; import com.google.common.base.Optional; +import com.google.common.base.Predicate; import com.google.gwt.core.client.Scheduler; import com.google.gwt.user.client.ui.AcceptsOneWidget; import com.google.inject.Inject; import com.google.inject.Singleton; import com.google.web.bindery.event.shared.EventBus; +import org.eclipse.che.api.promises.client.Operation; +import org.eclipse.che.api.promises.client.OperationException; import org.eclipse.che.commons.annotation.Nullable; import org.eclipse.che.ide.CoreLocalizationConstant; import org.eclipse.che.ide.Resources; +import org.eclipse.che.ide.api.action.Action; +import org.eclipse.che.ide.actions.common.ActionFactory; +import org.eclipse.che.ide.api.action.ActionManager; +import org.eclipse.che.ide.api.app.AppContext; import org.eclipse.che.ide.api.data.tree.Node; +import org.eclipse.che.ide.api.data.tree.TreeExpander; import org.eclipse.che.ide.api.data.tree.settings.NodeSettings; import org.eclipse.che.ide.api.data.tree.settings.SettingsProvider; +import org.eclipse.che.ide.api.keybinding.KeyBindingAgent; +import org.eclipse.che.ide.api.keybinding.KeyBuilder; import org.eclipse.che.ide.api.mvp.View; import org.eclipse.che.ide.api.parts.ProjectExplorerPart; import org.eclipse.che.ide.api.parts.base.BasePresenter; @@ -37,11 +47,13 @@ import org.eclipse.che.ide.api.selection.Selection; import org.eclipse.che.ide.api.workspace.event.WorkspaceStoppedEvent; import org.eclipse.che.ide.part.explorer.project.ProjectExplorerView.ActionDelegate; +import org.eclipse.che.ide.project.node.SyntheticNode; import org.eclipse.che.ide.project.node.SyntheticNodeUpdateEvent; import org.eclipse.che.ide.resource.Path; import org.eclipse.che.ide.resources.tree.ResourceNode; import org.eclipse.che.ide.ui.smartTree.NodeDescriptor; import org.eclipse.che.ide.ui.smartTree.Tree; +import org.eclipse.che.ide.ui.smartTree.event.BeforeExpandNodeEvent; import org.eclipse.che.ide.ui.smartTree.event.SelectionChangedEvent; import org.eclipse.che.ide.ui.smartTree.event.SelectionChangedEvent.SelectionChangedHandler; import org.eclipse.che.providers.DynaObject; @@ -50,6 +62,8 @@ import javax.validation.constraints.NotNull; import static com.google.common.base.MoreObjects.firstNonNull; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Iterables.any; import static org.eclipse.che.ide.api.resources.ResourceDelta.ADDED; import static org.eclipse.che.ide.api.resources.ResourceDelta.MOVED_FROM; import static org.eclipse.che.ide.api.resources.ResourceDelta.MOVED_TO; @@ -85,7 +99,11 @@ public ProjectExplorerPresenter(final ProjectExplorerView view, CoreLocalizationConstant locale, Resources resources, final ResourceNode.NodeFactory nodeFactory, - final SettingsProvider settingsProvider) { + final SettingsProvider settingsProvider, + ActionManager actionManager, + ActionFactory actionFactory, + final AppContext appContext, + KeyBindingAgent keyBindingAgent) { this.view = view; this.nodeFactory = nodeFactory; this.settingsProvider = settingsProvider; @@ -109,6 +127,78 @@ public void onSelectionChanged(SelectionChangedEvent event) { setSelection(new Selection<>(event.getSelection())); } }); + + view.getTree().addBeforeExpandHandler(new BeforeExpandNodeEvent.BeforeExpandNodeHandler() { + @Override + public void onBeforeExpand(BeforeExpandNodeEvent event) { + final NodeDescriptor nodeDescriptor = view.getTree().getNodeDescriptor(event.getNode()); + + if (event.getNode() instanceof SyntheticNode && nodeDescriptor != null && nodeDescriptor.isExpandDeep()) { + event.setCancelled(true); + } + } + }); + + final TreeExpander treeExpander = new TreeExpander() { + + private final boolean[] everExpanded = new boolean[]{false}; + + @Override + public void expandTree() { + if (everExpanded[0]) { + view.getTree().expandAll(); + + return; + } + + appContext.getWorkspaceRoot().getTree(-1).then(new Operation() { + @Override + public void apply(Resource[] ignored) throws OperationException { + everExpanded[0] = true; + + view.getTree().expandAll(); + } + }); + } + + @Override + public boolean isExpandEnabled() { + return view.getTree().getNodeStorage().getAllItemsCount() != 0; + } + + @Override + public void collapseTree() { + view.getTree().collapseAll(); + } + + @Override + public boolean isCollapseEnabled() { + return any(view.getTree().getRootNodes(), isExpanded()); + } + }; + + final Action expandTreeAction = actionFactory.createExpandTreeAction(treeExpander); + final Action collapseTreeAction = actionFactory.createCollapseTreeAction(treeExpander); + + final String expandTreeActionId = "expandProjectExplorerTree"; + final String collapseTreeActionId = "collapseProjectExplorerTree"; + + actionManager.registerAction(expandTreeActionId, expandTreeAction); + actionManager.registerAction(collapseTreeActionId, collapseTreeAction); + + keyBindingAgent.getGlobal().addKey(new KeyBuilder().action().charCode('[').build(), expandTreeActionId); + keyBindingAgent.getGlobal().addKey(new KeyBuilder().action().charCode(']').build(), collapseTreeActionId); + } + + private Predicate isExpanded() { + return new Predicate() { + @Override + public boolean apply(@javax.annotation.Nullable Node node) { + checkNotNull(node); + + return view.getTree().isExpanded(node); + } + }; } @Override 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 574dbb64884..8a31b825c22 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 @@ -631,10 +631,10 @@ Promise getRemoteResources(final Container container, final int dept return promises.resolve(NO_RESOURCES); } + int depthToReload = depth; final Optional descendants = store.getAll(container.getLocation()); - int depthToReload = depth; - if (descendants.isPresent()) { + if (depthToReload != -1 && descendants.isPresent()) { for (Resource resource : descendants.get()) { if (resource.getLocation().segmentCount() - container.getLocation().segmentCount() > depth) { depthToReload = resource.getLocation().segmentCount() - container.getLocation().segmentCount(); diff --git a/ide/che-core-ide-ui/src/main/java/org/eclipse/che/ide/ui/smartTree/Tree.java b/ide/che-core-ide-ui/src/main/java/org/eclipse/che/ide/ui/smartTree/Tree.java index dd7553aa355..00a5a9b0756 100644 --- a/ide/che-core-ide-ui/src/main/java/org/eclipse/che/ide/ui/smartTree/Tree.java +++ b/ide/che-core-ide-ui/src/main/java/org/eclipse/che/ide/ui/smartTree/Tree.java @@ -1163,6 +1163,10 @@ private void onExpand(Node node, NodeDescriptor nodeDescriptor, boolean deep) { } if (!fireCancellableEvent(new BeforeExpandNodeEvent(node))) { + if (deep) { + nodeDescriptor.setExpandDeep(false); + } + return; } From dba9a2c73b7bea0df66674a998a90b556b9ea984 Mon Sep 17 00:00:00 2001 From: Vladyslav Zhukovskii Date: Wed, 16 Nov 2016 15:49:31 +0200 Subject: [PATCH 2/6] Add unit tests for the actions --- .../che/ide/actions/common/ActionFactory.java | 16 ++-- ...pseAction.java => CollapseTreeAction.java} | 4 +- ...xpandAction.java => ExpandTreeAction.java} | 4 +- .../ide/actions/common/ActionFactoryTest.java | 57 +++++++++++++ .../common/CollapseTreeActionTest.java | 84 +++++++++++++++++++ .../actions/common/ExpandTreeActionTest.java | 84 +++++++++++++++++++ 6 files changed, 237 insertions(+), 12 deletions(-) rename ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/{TreeCollapseAction.java => CollapseTreeAction.java} (94%) rename ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/{TreeExpandAction.java => ExpandTreeAction.java} (94%) create mode 100644 ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/actions/common/ActionFactoryTest.java create mode 100644 ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/actions/common/CollapseTreeActionTest.java create mode 100644 ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/actions/common/ExpandTreeActionTest.java diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/ActionFactory.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/ActionFactory.java index 23e60354041..1d50ec24d95 100644 --- a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/ActionFactory.java +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/ActionFactory.java @@ -25,17 +25,17 @@ public class ActionFactory { /** - * Returns the instance of the {@link TreeExpandAction} based on the given {@code expander}. + * Returns the instance of the {@link ExpandTreeAction} based on the given {@code expander}. * * @param expander * tree expander - * @return instance of the {@link TreeExpandAction} - * @see TreeExpandAction + * @return instance of the {@link ExpandTreeAction} + * @see ExpandTreeAction * @see TreeExpander * @since 5.0.0 */ public Action createExpandTreeAction(final TreeExpander expander) { - return new TreeExpandAction() { + return new ExpandTreeAction() { @Override public TreeExpander getTreeExpander() { return expander; @@ -44,17 +44,17 @@ public TreeExpander getTreeExpander() { } /** - * Returns the instance of the {@link TreeCollapseAction} based on the given {@code expander}. + * Returns the instance of the {@link CollapseTreeAction} based on the given {@code expander}. * * @param expander * tree expander - * @return instance of the {@link TreeCollapseAction} - * @see TreeCollapseAction + * @return instance of the {@link CollapseTreeAction} + * @see CollapseTreeAction * @see TreeExpander * @since 5.0.0 */ public Action createCollapseTreeAction(final TreeExpander expander) { - return new TreeCollapseAction() { + return new CollapseTreeAction() { @Override public TreeExpander getTreeExpander() { return expander; diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/TreeCollapseAction.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/CollapseTreeAction.java similarity index 94% rename from ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/TreeCollapseAction.java rename to ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/CollapseTreeAction.java index aeaf671c5a8..55e1f4e0f5a 100644 --- a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/TreeCollapseAction.java +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/CollapseTreeAction.java @@ -23,11 +23,11 @@ * @see TreeExpander * @since 5.0.0 */ -public abstract class TreeCollapseAction extends Action { +public abstract class CollapseTreeAction extends Action { public abstract TreeExpander getTreeExpander(); - public TreeCollapseAction() { + public CollapseTreeAction() { super("Collapse All"); } diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/TreeExpandAction.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/ExpandTreeAction.java similarity index 94% rename from ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/TreeExpandAction.java rename to ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/ExpandTreeAction.java index 0a443eee4d3..6d6e0ed4519 100644 --- a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/TreeExpandAction.java +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/ExpandTreeAction.java @@ -23,11 +23,11 @@ * @see TreeExpander * @since 5.0.0 */ -public abstract class TreeExpandAction extends Action { +public abstract class ExpandTreeAction extends Action { public abstract TreeExpander getTreeExpander(); - public TreeExpandAction() { + public ExpandTreeAction() { super("Expand All"); } diff --git a/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/actions/common/ActionFactoryTest.java b/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/actions/common/ActionFactoryTest.java new file mode 100644 index 00000000000..19dc5ae278a --- /dev/null +++ b/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/actions/common/ActionFactoryTest.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2012-2016 Codenvy, S.A. + * 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: + * Codenvy, S.A. - initial API and implementation + *******************************************************************************/ +package org.eclipse.che.ide.actions.common; + +import com.google.gwtmockito.GwtMockitoTestRunner; + +import org.eclipse.che.ide.api.action.Action; +import org.eclipse.che.ide.api.data.tree.TreeExpander; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; + +import static org.junit.Assert.*; + +/** + * Unit tests for the {@link ActionFactory}. + * + * @author Vlad Zhukovskyi + */ +@RunWith(GwtMockitoTestRunner.class) +public class ActionFactoryTest { + + @Mock + TreeExpander treeExpander; + + private ActionFactory actionFactory; + + @Before + public void setUp() throws Exception { + actionFactory = new ActionFactory(); + } + + @Test + public void testShouldCreateTreeExpandAction() throws Exception { + final Action action = actionFactory.createExpandTreeAction(treeExpander); + + assertTrue(action instanceof ExpandTreeAction); + assertSame(((ExpandTreeAction)action).getTreeExpander(), treeExpander); + } + + @Test + public void testShouldCreateTreeCollapseAction() throws Exception { + final Action action = actionFactory.createCollapseTreeAction(treeExpander); + + assertTrue(action instanceof CollapseTreeAction); + assertSame(((CollapseTreeAction)action).getTreeExpander(), treeExpander); + } +} \ No newline at end of file diff --git a/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/actions/common/CollapseTreeActionTest.java b/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/actions/common/CollapseTreeActionTest.java new file mode 100644 index 00000000000..695d51affb1 --- /dev/null +++ b/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/actions/common/CollapseTreeActionTest.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2012-2016 Codenvy, S.A. + * 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: + * Codenvy, S.A. - initial API and implementation + *******************************************************************************/ +package org.eclipse.che.ide.actions.common; + +import com.google.gwtmockito.GwtMockitoTestRunner; + +import org.eclipse.che.ide.api.action.ActionEvent; +import org.eclipse.che.ide.api.action.Presentation; +import org.eclipse.che.ide.api.data.tree.TreeExpander; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; + +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +/** + * Unit tests for the {@link CollapseTreeAction}. + * + * @author Vlad Zhukovskyi + */ +@RunWith(GwtMockitoTestRunner.class) +public class CollapseTreeActionTest { + + @Mock + TreeExpander treeExpander; + @Mock + ActionEvent actionEvent; + @Mock + Presentation presentation; + + private CollapseTreeAction action; + + @Before + public void setUp() throws Exception { + action = new CollapseTreeAction() { + @Override + public TreeExpander getTreeExpander() { + return treeExpander; + } + }; + + when(actionEvent.getPresentation()).thenReturn(presentation); + } + + @Test + public void testShouldNotFireTreeCollapse() throws Exception { + when(treeExpander.isCollapseEnabled()).thenReturn(false); + + action.actionPerformed(actionEvent); + + verify(treeExpander, never()).collapseTree(); + } + + @Test + public void testShouldFireTreeCollapse() throws Exception { + when(treeExpander.isCollapseEnabled()).thenReturn(true); + + action.actionPerformed(actionEvent); + + verify(treeExpander).collapseTree(); + } + + @Test + public void testShouldUpdatePresentationBasedOnStatus() throws Exception { + when(treeExpander.isCollapseEnabled()).thenReturn(true); + + action.update(actionEvent); + + verify(presentation).setEnabledAndVisible(eq(true)); + } + +} \ No newline at end of file diff --git a/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/actions/common/ExpandTreeActionTest.java b/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/actions/common/ExpandTreeActionTest.java new file mode 100644 index 00000000000..69a045efc8b --- /dev/null +++ b/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/actions/common/ExpandTreeActionTest.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2012-2016 Codenvy, S.A. + * 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: + * Codenvy, S.A. - initial API and implementation + *******************************************************************************/ +package org.eclipse.che.ide.actions.common; + +import com.google.gwtmockito.GwtMockitoTestRunner; + +import org.eclipse.che.ide.api.action.ActionEvent; +import org.eclipse.che.ide.api.action.Presentation; +import org.eclipse.che.ide.api.data.tree.TreeExpander; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; + +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +/** + * Unit tests for the {@link ExpandTreeAction}. + * + * @author Vlad Zhukovskyi + */ +@RunWith(GwtMockitoTestRunner.class) +public class ExpandTreeActionTest { + + @Mock + TreeExpander treeExpander; + @Mock + ActionEvent actionEvent; + @Mock + Presentation presentation; + + private ExpandTreeAction action; + + @Before + public void setUp() throws Exception { + action = new ExpandTreeAction() { + @Override + public TreeExpander getTreeExpander() { + return treeExpander; + } + }; + + when(actionEvent.getPresentation()).thenReturn(presentation); + } + + @Test + public void testShouldNotFireTreeCollapse() throws Exception { + when(treeExpander.isExpandEnabled()).thenReturn(false); + + action.actionPerformed(actionEvent); + + verify(treeExpander, never()).expandTree(); + } + + @Test + public void testShouldFireTreeCollapse() throws Exception { + when(treeExpander.isExpandEnabled()).thenReturn(true); + + action.actionPerformed(actionEvent); + + verify(treeExpander).expandTree(); + } + + @Test + public void testShouldUpdatePresentationBasedOnStatus() throws Exception { + when(treeExpander.isExpandEnabled()).thenReturn(true); + + action.update(actionEvent); + + verify(presentation).setEnabledAndVisible(eq(true)); + } + +} \ No newline at end of file From 99d4e09b65788b2d776b89c46beb33cb4b823d4f Mon Sep 17 00:00:00 2001 From: Vladyslav Zhukovskii Date: Thu, 17 Nov 2016 12:43:32 +0200 Subject: [PATCH 3/6] Move project explorer tree expander to dedicate class --- .../project/ProjectExplorerPresenter.java | 54 +------------ .../project/ProjectExplorerTreeExpander.java | 80 +++++++++++++++++++ 2 files changed, 81 insertions(+), 53 deletions(-) create mode 100644 ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerTreeExpander.java diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerPresenter.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerPresenter.java index db80fc6b7ca..0b6d8ed99dc 100644 --- a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerPresenter.java +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerPresenter.java @@ -11,15 +11,12 @@ package org.eclipse.che.ide.part.explorer.project; import com.google.common.base.Optional; -import com.google.common.base.Predicate; import com.google.gwt.core.client.Scheduler; import com.google.gwt.user.client.ui.AcceptsOneWidget; import com.google.inject.Inject; import com.google.inject.Singleton; import com.google.web.bindery.event.shared.EventBus; -import org.eclipse.che.api.promises.client.Operation; -import org.eclipse.che.api.promises.client.OperationException; import org.eclipse.che.commons.annotation.Nullable; import org.eclipse.che.ide.CoreLocalizationConstant; import org.eclipse.che.ide.Resources; @@ -62,8 +59,6 @@ import javax.validation.constraints.NotNull; import static com.google.common.base.MoreObjects.firstNonNull; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.Iterables.any; import static org.eclipse.che.ide.api.resources.ResourceDelta.ADDED; import static org.eclipse.che.ide.api.resources.ResourceDelta.MOVED_FROM; import static org.eclipse.che.ide.api.resources.ResourceDelta.MOVED_TO; @@ -139,43 +134,7 @@ public void onBeforeExpand(BeforeExpandNodeEvent event) { } }); - final TreeExpander treeExpander = new TreeExpander() { - - private final boolean[] everExpanded = new boolean[]{false}; - - @Override - public void expandTree() { - if (everExpanded[0]) { - view.getTree().expandAll(); - - return; - } - - appContext.getWorkspaceRoot().getTree(-1).then(new Operation() { - @Override - public void apply(Resource[] ignored) throws OperationException { - everExpanded[0] = true; - - view.getTree().expandAll(); - } - }); - } - - @Override - public boolean isExpandEnabled() { - return view.getTree().getNodeStorage().getAllItemsCount() != 0; - } - - @Override - public void collapseTree() { - view.getTree().collapseAll(); - } - - @Override - public boolean isCollapseEnabled() { - return any(view.getTree().getRootNodes(), isExpanded()); - } - }; + final TreeExpander treeExpander = new ProjectExplorerTreeExpander(view.getTree(), appContext); final Action expandTreeAction = actionFactory.createExpandTreeAction(treeExpander); final Action collapseTreeAction = actionFactory.createCollapseTreeAction(treeExpander); @@ -190,17 +149,6 @@ public boolean isCollapseEnabled() { keyBindingAgent.getGlobal().addKey(new KeyBuilder().action().charCode(']').build(), collapseTreeActionId); } - private Predicate isExpanded() { - return new Predicate() { - @Override - public boolean apply(@javax.annotation.Nullable Node node) { - checkNotNull(node); - - return view.getTree().isExpanded(node); - } - }; - } - @Override public void onResourceChanged(ResourceChangedEvent event) { final Tree tree = view.getTree(); diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerTreeExpander.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerTreeExpander.java new file mode 100644 index 00000000000..fcf0827b408 --- /dev/null +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerTreeExpander.java @@ -0,0 +1,80 @@ +package org.eclipse.che.ide.part.explorer.project; + +import com.google.common.base.Predicate; + +import org.eclipse.che.api.promises.client.Operation; +import org.eclipse.che.api.promises.client.OperationException; +import org.eclipse.che.ide.api.app.AppContext; +import org.eclipse.che.ide.api.data.tree.Node; +import org.eclipse.che.ide.api.data.tree.TreeExpander; +import org.eclipse.che.ide.api.resources.Resource; +import org.eclipse.che.ide.ui.smartTree.Tree; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Iterables.any; + +/** + * Project explorer tree expander. Takes care about resources loading state, in case if tree has been never expanded before, it requests + * infinite resource tree from the server and then expands project tree on the UI. On the second time it just expands project tree without + * additional resource requests. + * + * @author Vlad Zhukovskyi + * @since 5.0.0 + * @see TreeExpander + */ +final class ProjectExplorerTreeExpander implements TreeExpander { + + private Tree tree; + private AppContext appContext; + + public ProjectExplorerTreeExpander(Tree tree, AppContext appContext) { + this.tree = tree; + this.appContext = appContext; + } + + private final boolean[] everExpanded = new boolean[]{false}; + + @Override + public void expandTree() { + if (everExpanded[0]) { + tree.expandAll(); + + return; + } + + appContext.getWorkspaceRoot().getTree(-1).then(new Operation() { + @Override + public void apply(Resource[] ignored) throws OperationException { + everExpanded[0] = true; + + tree.expandAll(); + } + }); + } + + @Override + public boolean isExpandEnabled() { + return tree.getNodeStorage().getAllItemsCount() != 0; + } + + @Override + public void collapseTree() { + tree.collapseAll(); + } + + @Override + public boolean isCollapseEnabled() { + return any(tree.getRootNodes(), isExpanded()); + } + + private Predicate isExpanded() { + return new Predicate() { + @Override + public boolean apply(@javax.annotation.Nullable Node node) { + checkNotNull(node); + + return tree.isExpanded(node); + } + }; + } +} From dee951f3148d4b5069a0af417727bfd92b20f5b1 Mon Sep 17 00:00:00 2001 From: Vladyslav Zhukovskii Date: Thu, 17 Nov 2016 14:03:42 +0200 Subject: [PATCH 4/6] Expose external JS API --- .../che/ide/actions/common/ActionFactory.java | 65 ------------------- .../project/ProjectExplorerPresenter.java | 48 +++++++++----- .../ide/actions/common/ActionFactoryTest.java | 57 ---------------- 3 files changed, 30 insertions(+), 140 deletions(-) delete mode 100644 ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/ActionFactory.java delete mode 100644 ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/actions/common/ActionFactoryTest.java diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/ActionFactory.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/ActionFactory.java deleted file mode 100644 index 1d50ec24d95..00000000000 --- a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/actions/common/ActionFactory.java +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012-2016 Codenvy, S.A. - * 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: - * Codenvy, S.A. - initial API and implementation - *******************************************************************************/ -package org.eclipse.che.ide.actions.common; - -import com.google.common.annotations.Beta; - -import org.eclipse.che.ide.api.action.Action; -import org.eclipse.che.ide.api.data.tree.TreeExpander; - -/** - * Utility methods to create basic common actions. - * - * @author Vlad Zhukovskyi - * @since 5.0.0 - */ -@Beta -public class ActionFactory { - - /** - * Returns the instance of the {@link ExpandTreeAction} based on the given {@code expander}. - * - * @param expander - * tree expander - * @return instance of the {@link ExpandTreeAction} - * @see ExpandTreeAction - * @see TreeExpander - * @since 5.0.0 - */ - public Action createExpandTreeAction(final TreeExpander expander) { - return new ExpandTreeAction() { - @Override - public TreeExpander getTreeExpander() { - return expander; - } - }; - } - - /** - * Returns the instance of the {@link CollapseTreeAction} based on the given {@code expander}. - * - * @param expander - * tree expander - * @return instance of the {@link CollapseTreeAction} - * @see CollapseTreeAction - * @see TreeExpander - * @since 5.0.0 - */ - public Action createCollapseTreeAction(final TreeExpander expander) { - return new CollapseTreeAction() { - @Override - public TreeExpander getTreeExpander() { - return expander; - } - }; - } - -} diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerPresenter.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerPresenter.java index 0b6d8ed99dc..92f3e630f6f 100644 --- a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerPresenter.java +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerPresenter.java @@ -20,16 +20,11 @@ import org.eclipse.che.commons.annotation.Nullable; import org.eclipse.che.ide.CoreLocalizationConstant; import org.eclipse.che.ide.Resources; -import org.eclipse.che.ide.api.action.Action; -import org.eclipse.che.ide.actions.common.ActionFactory; -import org.eclipse.che.ide.api.action.ActionManager; import org.eclipse.che.ide.api.app.AppContext; import org.eclipse.che.ide.api.data.tree.Node; import org.eclipse.che.ide.api.data.tree.TreeExpander; import org.eclipse.che.ide.api.data.tree.settings.NodeSettings; import org.eclipse.che.ide.api.data.tree.settings.SettingsProvider; -import org.eclipse.che.ide.api.keybinding.KeyBindingAgent; -import org.eclipse.che.ide.api.keybinding.KeyBuilder; import org.eclipse.che.ide.api.mvp.View; import org.eclipse.che.ide.api.parts.ProjectExplorerPart; import org.eclipse.che.ide.api.parts.base.BasePresenter; @@ -83,6 +78,7 @@ public class ProjectExplorerPresenter extends BasePresenter implements ActionDel private final SettingsProvider settingsProvider; private final CoreLocalizationConstant locale; private final Resources resources; + private final TreeExpander treeExpander; private static final int PART_SIZE = 500; @@ -95,10 +91,7 @@ public ProjectExplorerPresenter(final ProjectExplorerView view, Resources resources, final ResourceNode.NodeFactory nodeFactory, final SettingsProvider settingsProvider, - ActionManager actionManager, - ActionFactory actionFactory, - final AppContext appContext, - KeyBindingAgent keyBindingAgent) { + final AppContext appContext) { this.view = view; this.nodeFactory = nodeFactory; this.settingsProvider = settingsProvider; @@ -134,19 +127,38 @@ public void onBeforeExpand(BeforeExpandNodeEvent event) { } }); - final TreeExpander treeExpander = new ProjectExplorerTreeExpander(view.getTree(), appContext); + treeExpander = new ProjectExplorerTreeExpander(view.getTree(), appContext); - final Action expandTreeAction = actionFactory.createExpandTreeAction(treeExpander); - final Action collapseTreeAction = actionFactory.createCollapseTreeAction(treeExpander); + registerNative(); + } + + /* Expose Project Explorer's internal API to the world, to allow automated Selenium scripts expand all projects tree. */ + private native void registerNative() /*-{ + var that = this; + + var ProjectExplorer = {}; + + ProjectExplorer.expandAll = $entry(function() { + that.@org.eclipse.che.ide.part.explorer.project.ProjectExplorerPresenter::doExpand()(); + }) - final String expandTreeActionId = "expandProjectExplorerTree"; - final String collapseTreeActionId = "collapseProjectExplorerTree"; + ProjectExplorer.collapeAll = $entry(function() { + that.@org.eclipse.che.ide.part.explorer.project.ProjectExplorerPresenter::doCollapse()(); + }) - actionManager.registerAction(expandTreeActionId, expandTreeAction); - actionManager.registerAction(collapseTreeActionId, collapseTreeAction); + $wnd.IDE.ProjectExplorer = ProjectExplorer; + }-*/; - keyBindingAgent.getGlobal().addKey(new KeyBuilder().action().charCode('[').build(), expandTreeActionId); - keyBindingAgent.getGlobal().addKey(new KeyBuilder().action().charCode(']').build(), collapseTreeActionId); + private void doExpand() { + if (treeExpander.isExpandEnabled()) { + treeExpander.expandTree(); + } + } + + private void doCollapse() { + if (treeExpander.isCollapseEnabled()) { + treeExpander.collapseTree(); + } } @Override diff --git a/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/actions/common/ActionFactoryTest.java b/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/actions/common/ActionFactoryTest.java deleted file mode 100644 index 19dc5ae278a..00000000000 --- a/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/actions/common/ActionFactoryTest.java +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012-2016 Codenvy, S.A. - * 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: - * Codenvy, S.A. - initial API and implementation - *******************************************************************************/ -package org.eclipse.che.ide.actions.common; - -import com.google.gwtmockito.GwtMockitoTestRunner; - -import org.eclipse.che.ide.api.action.Action; -import org.eclipse.che.ide.api.data.tree.TreeExpander; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; - -import static org.junit.Assert.*; - -/** - * Unit tests for the {@link ActionFactory}. - * - * @author Vlad Zhukovskyi - */ -@RunWith(GwtMockitoTestRunner.class) -public class ActionFactoryTest { - - @Mock - TreeExpander treeExpander; - - private ActionFactory actionFactory; - - @Before - public void setUp() throws Exception { - actionFactory = new ActionFactory(); - } - - @Test - public void testShouldCreateTreeExpandAction() throws Exception { - final Action action = actionFactory.createExpandTreeAction(treeExpander); - - assertTrue(action instanceof ExpandTreeAction); - assertSame(((ExpandTreeAction)action).getTreeExpander(), treeExpander); - } - - @Test - public void testShouldCreateTreeCollapseAction() throws Exception { - final Action action = actionFactory.createCollapseTreeAction(treeExpander); - - assertTrue(action instanceof CollapseTreeAction); - assertSame(((CollapseTreeAction)action).getTreeExpander(), treeExpander); - } -} \ No newline at end of file From fed733c92537dd537cac0e1a0931d848473ad818 Mon Sep 17 00:00:00 2001 From: Vladyslav Zhukovskii Date: Thu, 17 Nov 2016 14:06:15 +0200 Subject: [PATCH 5/6] Typo fix --- .../che/ide/part/explorer/project/ProjectExplorerPresenter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerPresenter.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerPresenter.java index 92f3e630f6f..8ad663012cd 100644 --- a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerPresenter.java +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerPresenter.java @@ -142,7 +142,7 @@ private native void registerNative() /*-{ that.@org.eclipse.che.ide.part.explorer.project.ProjectExplorerPresenter::doExpand()(); }) - ProjectExplorer.collapeAll = $entry(function() { + ProjectExplorer.collapseAll = $entry(function() { that.@org.eclipse.che.ide.part.explorer.project.ProjectExplorerPresenter::doCollapse()(); }) From 00174ab81f3af14ffeb5af223acc5eb37ada8ecb Mon Sep 17 00:00:00 2001 From: Vladyslav Zhukovskii Date: Thu, 17 Nov 2016 14:39:41 +0200 Subject: [PATCH 6/6] Add new line --- .../eclipse/che/ide/actions/common/CollapseTreeActionTest.java | 2 +- .../eclipse/che/ide/actions/common/ExpandTreeActionTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/actions/common/CollapseTreeActionTest.java b/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/actions/common/CollapseTreeActionTest.java index 695d51affb1..39dee853f54 100644 --- a/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/actions/common/CollapseTreeActionTest.java +++ b/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/actions/common/CollapseTreeActionTest.java @@ -81,4 +81,4 @@ public void testShouldUpdatePresentationBasedOnStatus() throws Exception { verify(presentation).setEnabledAndVisible(eq(true)); } -} \ No newline at end of file +} diff --git a/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/actions/common/ExpandTreeActionTest.java b/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/actions/common/ExpandTreeActionTest.java index 69a045efc8b..ab6556b3845 100644 --- a/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/actions/common/ExpandTreeActionTest.java +++ b/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/actions/common/ExpandTreeActionTest.java @@ -81,4 +81,4 @@ public void testShouldUpdatePresentationBasedOnStatus() throws Exception { verify(presentation).setEnabledAndVisible(eq(true)); } -} \ No newline at end of file +}