/*******************************************************************************
* Copyright (c) 2012-2015 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.ext.java.client.editor;
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.project.tree.TreeNode;
import org.eclipse.che.ide.api.project.tree.TreeStructure;
import org.eclipse.che.ide.api.project.tree.VirtualFile;
import org.eclipse.che.ide.api.project.tree.generic.ProjectNode;
import org.eclipse.che.ide.collections.StringMap;
import org.eclipse.che.ide.ext.java.client.navigation.JavaNavigationService;
import org.eclipse.che.ide.ext.java.client.projecttree.JavaTreeStructure;
import org.eclipse.che.ide.ext.java.messages.JavadocHandleComputed;
import org.eclipse.che.ide.ext.java.shared.OpenDeclarationDescriptor;
import org.eclipse.che.ide.jseditor.client.text.LinearRange;
import org.eclipse.che.ide.jseditor.client.texteditor.EmbeddedTextEditorPresenter;
import org.eclipse.che.ide.rest.AsyncRequestCallback;
import org.eclipse.che.ide.rest.DtoUnmarshallerFactory;
import org.eclipse.che.ide.rest.Unmarshallable;
import org.eclipse.che.ide.util.loging.Log;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.Inject;
import com.google.inject.Singleton;
/**
* @author Evgen Vidolob
*/
@Singleton
public class OpenDeclarationFinder {
private final JavaParserWorker worker;
private final EditorAgent editorAgent;
private final JavaNavigationService service;
private DtoUnmarshallerFactory factory;
private JavaNavigationService navigationService;
private AppContext context;
@Inject
public OpenDeclarationFinder(JavaParserWorker worker, EditorAgent editorAgent, JavaNavigationService service,
DtoUnmarshallerFactory factory, JavaNavigationService navigationService, AppContext context) {
this.worker = worker;
this.editorAgent = editorAgent;
this.service = service;
this.factory = factory;
this.navigationService = navigationService;
this.context = context;
}
public void openDeclaration() {
EditorPartPresenter activeEditor = editorAgent.getActiveEditor();
if (activeEditor == null) {
return;
}
if (!(activeEditor instanceof EmbeddedTextEditorPresenter)) {
Log.error(getClass(), "Open Declaration support only EmbeddedTextEditorPresenter as editor");
return;
}
EmbeddedTextEditorPresenter editor = ((EmbeddedTextEditorPresenter)activeEditor);
int offset = editor.getCursorOffset();
final VirtualFile file = editor.getEditorInput().getFile();
worker.computeJavadocHandle(offset, file.getPath(), new JavaParserWorker.Callback<JavadocHandleComputed>() {
@Override
public void onCallback(JavadocHandleComputed result) {
if (result != null) {
handle(result, file);
}
}
});
}
private void handle(JavadocHandleComputed result, VirtualFile file) {
if (result.getOffset() != -1 && result.isSource()) {
EditorPartPresenter editorPartPresenter = editorAgent.getActiveEditor();
fileOpened(editorPartPresenter, result.getOffset());
} else {
sendRequest(result.getKey(), file.getProject());
}
}
private void sendRequest(String bindingKey, ProjectNode project) {
Unmarshallable<OpenDeclarationDescriptor> unmarshaller =
factory.newUnmarshaller(OpenDeclarationDescriptor.class);
service.findDeclaration(project.getPath(), bindingKey, new AsyncRequestCallback<OpenDeclarationDescriptor>(unmarshaller) {
@Override
protected void onSuccess(OpenDeclarationDescriptor result) {
if (result != null) {
handleDescriptor(result);
}
}
@Override
protected void onFailure(Throwable exception) {
Log.error(OpenDeclarationFinder.class, exception);
}
});
}
private void handleDescriptor(final OpenDeclarationDescriptor descriptor) {
StringMap<EditorPartPresenter> openedEditors = editorAgent.getOpenedEditors();
for (String s : openedEditors.getKeys().asIterable()) {
if (descriptor.getPath().equals(s)) {
EditorPartPresenter editorPartPresenter = openedEditors.get(s);
editorAgent.activateEditor(editorPartPresenter);
fileOpened(editorPartPresenter, descriptor.getOffset());
return;
}
}
TreeStructure tree = context.getCurrentProject().getCurrentTree();
if (descriptor.isBinary()) {
if (tree instanceof JavaTreeStructure) {
((JavaTreeStructure)tree)
.getClassFileByPath(context.getCurrentProject().getProjectDescription().getPath(), descriptor.getLibId(),
descriptor.getPath(), new AsyncCallback<TreeNode<?>>() {
@Override
public void onFailure(Throwable caught) {
Log.error(OpenDeclarationFinder.class, caught);
}
@Override
public void onSuccess(TreeNode<?> result) {
if (result instanceof VirtualFile) {
openFile((VirtualFile)result, descriptor);
}
}
});
}
} else {
tree.getNodeByPath(descriptor.getPath(), new AsyncCallback<TreeNode<?>>() {
@Override
public void onFailure(Throwable caught) {
Log.error(OpenDeclarationFinder.class, caught);
}
@Override
public void onSuccess(TreeNode<?> result) {
if (result instanceof VirtualFile) {
openFile((VirtualFile)result, descriptor);
}
}
});
}
}
private void openFile(VirtualFile result, final OpenDeclarationDescriptor descriptor) {
editorAgent.openEditor(result, new EditorAgent.OpenEditorCallback() {
@Override
public void onEditorOpened(EditorPartPresenter editor) {
fileOpened(editor, descriptor.getOffset());
}
});
}
private void fileOpened(EditorPartPresenter editor, int offset) {
if (editor instanceof EmbeddedTextEditorPresenter) {
((EmbeddedTextEditorPresenter)editor).getDocument().setSelectedRange(
LinearRange.createWithStart(offset).andLength(0), true);
}
}
}