Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CHE-1448: Fix cyclic request sending and possible NPE #1690

Merged
merged 3 commits into from
Jul 8, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import org.eclipse.che.api.promises.client.Operation;
import org.eclipse.che.api.promises.client.OperationException;
import org.eclipse.che.api.promises.client.PromiseError;
import org.eclipse.che.commons.annotation.Nullable;
import org.eclipse.che.ide.CoreLocalizationConstant;
import org.eclipse.che.ide.Resources;
Expand Down Expand Up @@ -91,6 +92,11 @@ private void onAccepted(String value) {
public void apply(Folder folder) throws OperationException {
eventBus.fireEvent(new RevealResourceEvent(folder));
}
}).catchError(new Operation<PromiseError>() {
@Override
public void apply(PromiseError error) throws OperationException {
dialogFactory.createMessageDialog("Error", error.getMessage(), null).show();
}
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
package org.eclipse.che.ide.part.explorer.project;

import com.google.common.base.MoreObjects;
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;
Expand Down Expand Up @@ -275,20 +276,36 @@ private void onResourceRemoved(final ResourceDelta delta) {
final Tree tree = view.getTree();
final Resource resource = delta.getResource();

final Node node = getNode(resource.getLocation());

if (node == null) {
return;
}

if (resource.getLocation().segmentCount() == 1) {
final Node projectNode = getNode(resource.getLocation());
tree.getNodeStorage().remove(node);
return;
}

if (projectNode != null) {
tree.getNodeStorage().remove(projectNode);
}
final Node parentNode = getParentNode(resource.getLocation());

if (parentNode == null) {
return;
}

final Node node = getParentNode(delta.getResource().getLocation());
final Path parentLocation = ((ResourceNode)parentNode).getData().getLocation();

if (node != null && tree.isExpanded(node)) {
tree.getNodeLoader().loadChildren(node, true);
if (resource.getLocation().parent().equals(parentLocation)) {
tree.getNodeStorage().remove(node);
} else {
tree.getNodeStorage().remove(node);

Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
@Override
public void execute() {
tree.getNodeLoader().loadChildren(parentNode, true);
}
});
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ public List<ActionDescriptor> getActions() {
Then check if child is resource, then we store the path in user preference.
*/

outer:
for (Node node : projectExplorer.getTree().getNodeStorage().getAll()) {
if (projectExplorer.getTree().isExpanded(node) && node instanceof ResourceNode) {

Expand All @@ -101,6 +102,7 @@ public List<ActionDescriptor> getActions() {
for (Node children : childrenToStore) {
if (children instanceof ResourceNode) {
paths.add(((ResourceNode)children).getData().getLocation());
continue outer;
}
}
}
Expand Down Expand Up @@ -145,14 +147,14 @@ public void actionPerformed(ActionEvent e) {

for (final String path : paths) {
if (revealPromise == null) {
revealPromise = revealer.reveal(Path.valueOf(path)).thenPromise(new Function<Node, Promise<Node>>() {
revealPromise = revealer.reveal(Path.valueOf(path), false).thenPromise(new Function<Node, Promise<Node>>() {
@Override
public Promise<Node> apply(Node node) throws FunctionException {
if (node != null) {
projectExplorer.getTree().setExpanded(node, true, false);
}

return revealer.reveal(Path.valueOf(path));
return revealer.reveal(Path.valueOf(path), false);
}
});
continue;
Expand All @@ -165,7 +167,7 @@ public Promise<Node> apply(Node node) throws FunctionException {
projectExplorer.getTree().setExpanded(node, true, false);
}

return revealer.reveal(Path.valueOf(path));
return revealer.reveal(Path.valueOf(path), false);
}
}).catchError(new Function<PromiseError, Node>() {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,21 +110,34 @@ public Void apply(PromiseError arg) throws FunctionException {
* @return promise object with found node or promise error if node wasn't found
*/
public Promise<Node> reveal(final Path path) {
return reveal(path, true);
}

/**
* Search node in the project explorer tree by storable path.
*
* @param path
* path to node
* @param select
* select node after reveal
* @return promise object with found node or promise error if node wasn't found
*/
public Promise<Node> reveal(final Path path, final boolean select) {

return queue.thenPromise(new Function<Void, Promise<Node>>() {
@Override
public Promise<Node> apply(Void ignored) throws FunctionException {
return createFromAsyncRequest(new RequestCall<Node>() {
@Override
public void makeCall(AsyncCallback<Node> callback) {
reveal(path, callback);
reveal(path, select, callback);
}
});
}
});
}

protected void reveal(final Path path, final AsyncCallback<Node> callback) {
protected void reveal(final Path path, final boolean select, final AsyncCallback<Node> callback) {
if (path == null) {
callback.onFailure(new IllegalArgumentException("Invalid search path"));
}
Expand All @@ -150,7 +163,7 @@ public boolean execute() {
return false;
}

expandToPath(root, path).then(new Operation<ResourceNode>() {
expandToPath(root, path, select).then(new Operation<ResourceNode>() {
@Override
public void apply(ResourceNode node) throws OperationException {
callback.onSuccess(node);
Expand All @@ -168,27 +181,29 @@ public void apply(PromiseError arg) throws OperationException {

}

private Promise<ResourceNode> expandToPath(final ResourceNode root, final Path path) {
private Promise<ResourceNode> expandToPath(final ResourceNode root, final Path path, final boolean select) {
return createFromAsyncRequest(new RequestCall<ResourceNode>() {
@Override
public void makeCall(final AsyncCallback<ResourceNode> callback) {
expand(root, path, callback);
expand(root, path, select, callback);
}
});
}

protected void expand(final ResourceNode parent, final Path segment, final AsyncCallback<ResourceNode> callback) {
protected void expand(final ResourceNode parent, final Path segment, final boolean select, final AsyncCallback<ResourceNode> callback) {

if (parent.getData().getLocation().equals(segment)) {
if (toSelect == null) {
toSelect = new Node[]{parent};
} else {
final int index = toSelect.length;
toSelect = copyOf(toSelect, index + 1);
toSelect[index] = parent;
}
if (select) {
if (toSelect == null) {
toSelect = new Node[]{parent};
} else {
final int index = toSelect.length;
toSelect = copyOf(toSelect, index + 1);
toSelect[index] = parent;
}

selectTask.delay(200);
selectTask.delay(200);
}

callback.onSuccess(parent);
return;
Expand All @@ -212,7 +227,7 @@ public void onPostLoad(PostLoadEvent event) {

for (Node child : children) {
if (child instanceof ResourceNode && ((ResourceNode)child).getData().getLocation().isPrefixOf(segment)) {
expand((ResourceNode)child, segment, callback);
expand((ResourceNode)child, segment, select, callback);
return;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ public void onResourceChanged(ResourceChangedEvent event) {

if (file.getLocation().equals(movedFrom)) {
file = (VirtualFile)resource;
title.setText(file.getDisplayName());
}
} else if (delta.getKind() == UPDATED) {
if (!delta.getResource().isFile()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ public Optional<Resource[]> getAll(Path parent) {

final Path comparedPath = setEntry.getKey();

if (parent.segmentCount() > comparedPath.segmentCount() && !parent.isPrefixOf(comparedPath)) {
if (!parent.isPrefixOf(comparedPath)) {
continue;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import org.eclipse.che.api.promises.client.PromiseError;
import org.eclipse.che.api.promises.client.js.Promises;
import org.eclipse.che.commons.annotation.Nullable;
import org.eclipse.che.ide.DelayedTask;
import org.eclipse.che.ide.api.data.tree.Node;
import org.eclipse.che.ide.api.data.tree.NodeInterceptor;
import org.eclipse.che.ide.ui.smartTree.event.BeforeLoadEvent;
Expand Down Expand Up @@ -62,31 +61,6 @@ public class NodeLoader implements LoaderHandler.HasLoaderHandlers {
*/
Map<Node, Boolean> childRequested = new HashMap<>();

/**
* Load queue need to load nodes in batch mode.
*/
Map<Node, Boolean> loadQueue = new HashMap<>();

/**
* Load task takes nodes from {@link #loadQueue} and load them in specific time frame.
*/
DelayedTask loadTask = new DelayedTask() {
@Override
public void onExecute() {
for (Map.Entry<Node, Boolean> entry : loadQueue.entrySet()) {
if (childRequested.containsKey(entry.getKey())) {
continue;
}

childRequested.put(entry.getKey(), entry.getValue());

doLoad(entry.getKey());
}

loadQueue.clear();
}
};

/**
* Last processed node. Maybe used in general purpose.
*/
Expand Down Expand Up @@ -315,10 +289,12 @@ public boolean loadChildren(Node parent, boolean reloadExpandedChild) {
return false;
}

loadQueue.put(parent, reloadExpandedChild);
loadTask.delay(100);
if (childRequested.containsKey(parent)) {
return false;
}

return true;
childRequested.put(parent, reloadExpandedChild);
return doLoad(parent);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.che.ide.ext.java.client.action;

import com.google.common.base.Optional;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.web.bindery.event.shared.EventBus;
Expand All @@ -25,11 +26,11 @@
import org.eclipse.che.ide.api.notification.NotificationManager;
import org.eclipse.che.ide.api.resources.Container;
import org.eclipse.che.ide.api.resources.Folder;
import org.eclipse.che.ide.api.resources.Project;
import org.eclipse.che.ide.api.resources.Resource;
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.JavaUtils;
import org.eclipse.che.ide.ext.java.client.resource.SourceFolderMarker;
import org.eclipse.che.ide.newresource.AbstractNewResourceAction;
import org.eclipse.che.ide.api.dialogs.InputCallback;
import org.eclipse.che.ide.api.dialogs.InputDialog;
Expand All @@ -39,6 +40,7 @@
import javax.validation.constraints.NotNull;

import static com.google.common.base.Preconditions.checkState;
import static org.eclipse.che.ide.ext.java.client.resource.SourceFolderMarker.ID;
import static org.eclipse.che.ide.ext.java.client.util.JavaUtil.isJavaProject;

/**
Expand Down Expand Up @@ -67,10 +69,19 @@ public NewPackageAction(JavaResources javaResources,

@Override
public void updateInPerspective(@NotNull ActionEvent e) {
final Resource[] resources = appContext.getResources();
final boolean inJavaProject = resources != null && resources.length == 1 && isJavaProject(resources[0].getRelatedProject().get());
final Resource resource = appContext.getResource();
if (resource == null) {
e.getPresentation().setEnabledAndVisible(false);
return;
}

final Optional<Project> project = resource.getRelatedProject();
if (!project.isPresent()) {
e.getPresentation().setEnabledAndVisible(false);
return;
}

e.getPresentation().setEnabledAndVisible(inJavaProject && resources[0].getParentWithMarker(SourceFolderMarker.ID).isPresent());
e.getPresentation().setEnabledAndVisible(isJavaProject(project.get()) && resource.getParentWithMarker(ID).isPresent());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,22 @@
*******************************************************************************/
package org.eclipse.che.ide.ext.java.client.action;

import com.google.common.base.Optional;
import com.google.inject.Inject;
import com.google.inject.Singleton;

import org.eclipse.che.ide.api.action.AbstractPerspectiveAction;
import org.eclipse.che.ide.api.action.ActionEvent;
import org.eclipse.che.ide.api.app.AppContext;
import org.eclipse.che.ide.api.resources.Project;
import org.eclipse.che.ide.api.resources.Resource;
import org.eclipse.che.ide.ext.java.client.JavaLocalizationConstant;
import org.eclipse.che.ide.ext.java.client.project.classpath.ProjectClasspathPresenter;

import javax.validation.constraints.NotNull;
import java.util.Collections;

import static org.eclipse.che.ide.ext.java.client.resource.SourceFolderMarker.ID;
import static org.eclipse.che.ide.ext.java.client.util.JavaUtil.isJavaProject;
import static org.eclipse.che.ide.workspace.perspectives.project.ProjectPerspective.PROJECT_PERSPECTIVE_ID;

Expand Down Expand Up @@ -57,8 +60,18 @@ public void actionPerformed(ActionEvent e) {

@Override
public void updateInPerspective(@NotNull ActionEvent event) {
final Resource[] resources = appContext.getResources();
final Resource resource = appContext.getResource();
if (resource == null) {
event.getPresentation().setEnabledAndVisible(false);
return;
}

event.getPresentation().setEnabledAndVisible(resources != null && resources.length == 1 && isJavaProject(resources[0].getRelatedProject().get()));
final Optional<Project> project = resource.getRelatedProject();
if (!project.isPresent()) {
event.getPresentation().setEnabledAndVisible(false);
return;
}

event.getPresentation().setEnabledAndVisible(isJavaProject(project.get()) && resource.getParentWithMarker(ID).isPresent());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ public void update(ActionEvent event) {
final Resource resource = resources[0];

final Optional<Project> project = resource.getRelatedProject();

if (!project.isPresent()) {
event.getPresentation().setEnabled(false);
return;
}

final Optional<Resource> srcFolder = resource.getParentWithMarker(SourceFolderMarker.ID);

if (resource.getResourceType() == FILE) {
Expand Down
Loading