/******************************************************************************* * Copyright (c) 2012-2017 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.navigation.filestructure; import com.google.common.base.Optional; import com.google.gwt.core.client.Scheduler; import com.google.inject.Inject; import com.google.inject.Singleton; 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.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.OpenEditorCallbackImpl; import org.eclipse.che.ide.api.editor.text.LinearRange; import org.eclipse.che.ide.api.editor.texteditor.TextEditor; 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.api.resources.SyntheticFile; import org.eclipse.che.ide.api.resources.VirtualFile; import org.eclipse.che.ide.ext.java.client.navigation.service.JavaNavigationService; 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.ext.java.shared.JarEntry; import org.eclipse.che.ide.ext.java.shared.dto.ClassContent; import org.eclipse.che.ide.ext.java.shared.dto.Region; import org.eclipse.che.ide.ext.java.shared.dto.model.CompilationUnit; import org.eclipse.che.ide.ext.java.shared.dto.model.Member; import org.eclipse.che.ide.resource.Path; import org.eclipse.che.ide.ui.loaders.request.LoaderFactory; import org.eclipse.che.ide.ui.loaders.request.MessageLoader; import org.eclipse.che.ide.util.loging.Log; /** * The class that manages class structure window. * * @author Valeriy Svydenko * @author Vlad Zhukovskyi */ @Singleton public class FileStructurePresenter implements FileStructure.ActionDelegate { private final FileStructure view; private final JavaNavigationService javaNavigationService; private final AppContext context; private final EditorAgent editorAgent; private final MessageLoader loader; private TextEditor activeEditor; private boolean showInheritedMembers; private int cursorOffset; @Inject public FileStructurePresenter(FileStructure view, JavaNavigationService javaNavigationService, AppContext context, EditorAgent editorAgent, LoaderFactory loaderFactory) { this.view = view; this.javaNavigationService = javaNavigationService; this.context = context; this.editorAgent = editorAgent; this.loader = loaderFactory.newLoader(); this.view.setDelegate(this); } /** * Shows the structure of the opened class. * * @param editorPartPresenter * the active editor */ public void show(EditorPartPresenter editorPartPresenter) { loader.show(); view.setTitle(editorPartPresenter.getEditorInput().getFile().getName()); if (!(editorPartPresenter instanceof TextEditor)) { Log.error(getClass(), "Open Declaration support only TextEditor as editor"); return; } activeEditor = ((TextEditor)editorPartPresenter); cursorOffset = activeEditor.getCursorOffset(); VirtualFile file = activeEditor.getEditorInput().getFile(); if (file instanceof Resource) { final Optional<Project> project = ((Resource)file).getRelatedProject(); final Optional<Resource> srcFolder = ((Resource)file).getParentWithMarker(SourceFolderMarker.ID); if (!srcFolder.isPresent()) { return; } final String fqn = JavaUtil.resolveFQN((Container)srcFolder.get(), (Resource)file); javaNavigationService.getCompilationUnit(project.get().getLocation(), fqn, showInheritedMembers).then( new Operation<CompilationUnit>() { @Override public void apply(CompilationUnit unit) throws OperationException { view.setStructure(unit, showInheritedMembers); showInheritedMembers = !showInheritedMembers; loader.hide(); view.show(); } }).catchError(new Operation<PromiseError>() { @Override public void apply(PromiseError arg) throws OperationException { Log.error(FileStructurePresenter.class, arg.getMessage()); loader.hide(); } }); } } /** {@inheritDoc} */ @Override public void actionPerformed(final Member member) { if (member.isBinary()) { final Resource resource = context.getResource(); if (resource == null) { return; } final Optional<Project> project = resource.getRelatedProject(); javaNavigationService.getEntry(project.get().getLocation(), member.getLibId(), member.getRootPath()) .then(new Operation<JarEntry>() { @Override public void apply(final JarEntry entry) throws OperationException { javaNavigationService .getContent(project.get().getLocation(), member.getLibId(), Path.valueOf(entry.getPath())) .then(new Operation<ClassContent>() { @Override public void apply(ClassContent content) throws OperationException { final String clazz = entry.getName().substring(0, entry.getName().indexOf('.')); final VirtualFile file = new SyntheticFile(entry.getName(), clazz, content.getContent()); editorAgent.openEditor(file, new OpenEditorCallbackImpl() { @Override public void onEditorOpened(EditorPartPresenter editor) { setCursor(editor, member.getFileRegion().getOffset()); } }); } }); } }); } else { context.getWorkspaceRoot().getFile(member.getRootPath()).then(new Operation<Optional<File>>() { @Override public void apply(Optional<File> file) throws OperationException { if (file.isPresent()) { editorAgent.openEditor(file.get(), new OpenEditorCallbackImpl() { @Override public void onEditorOpened(EditorPartPresenter editor) { setCursor(editor, member.getFileRegion().getOffset()); } }); } } }); } Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() { @Override public void execute() { setCursorPosition(member.getFileRegion()); } }); showInheritedMembers = false; } @Override public void onEscapeClicked() { activeEditor.setFocus(); setCursor(activeEditor, cursorOffset); } private void setCursorPosition(Region region) { LinearRange linearRange = LinearRange.createWithStart(region.getOffset()).andLength(region.getLength()); activeEditor.setFocus(); activeEditor.getDocument().setSelectedRange(linearRange, true); } private void setCursor(EditorPartPresenter editor, int offset) { if (editor instanceof TextEditor) { ((TextEditor)editor).getDocument().setSelectedRange(LinearRange.createWithStart(offset).andLength(0), true); } } }