/******************************************************************************* * 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.search.node; import elemental.html.SpanElement; import com.google.common.base.Optional; import com.google.gwt.core.client.Scheduler; import com.google.gwt.dom.client.Element; import com.google.inject.Inject; import com.google.inject.assistedinject.Assisted; 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.commons.annotation.Nullable; import org.eclipse.che.ide.api.app.AppContext; import org.eclipse.che.ide.api.data.tree.HasAction; import org.eclipse.che.ide.api.data.tree.Node; 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.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.JavaResources; import org.eclipse.che.ide.ext.java.client.navigation.service.JavaNavigationService; 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.ClassFile; import org.eclipse.che.ide.ext.java.shared.dto.model.CompilationUnit; import org.eclipse.che.ide.ext.java.shared.dto.search.Match; import org.eclipse.che.ide.resource.Path; import org.eclipse.che.ide.ui.smartTree.TreeStyles; import org.eclipse.che.ide.ui.smartTree.presentation.NodePresentation; import org.eclipse.che.ide.util.dom.Elements; import javax.validation.constraints.NotNull; import java.util.List; /** * Node represent Match for find usages search. * * @author Evgen Vidolob */ public class MatchNode extends AbstractPresentationNode implements HasAction { private TreeStyles styles; private JavaResources resources; private EditorAgent editorAgent; private AppContext appContext; private Match match; private CompilationUnit compilationUnit; private ClassFile classFile; private final JavaNavigationService service; @Inject public MatchNode(TreeStyles styles, JavaResources resources, EditorAgent editorAgent, AppContext appContext, @Assisted Match match, @Nullable @Assisted CompilationUnit compilationUnit, @Nullable @Assisted ClassFile classFile, JavaNavigationService service) { this.styles = styles; this.resources = resources; this.editorAgent = editorAgent; this.appContext = appContext; this.match = match; this.compilationUnit = compilationUnit; this.classFile = classFile; this.service = service; } @Override protected Promise<List<Node>> getChildrenImpl() { return null; } @Override public void updatePresentation(@NotNull NodePresentation presentation) { SpanElement spanElement = Elements.createSpanElement(styles.styles().presentableTextContainer()); SpanElement lineNumberElement = Elements.createSpanElement(); lineNumberElement.setInnerHTML(String.valueOf(match.getMatchLineNumber() + 1) + ":   "); spanElement.appendChild(lineNumberElement); SpanElement textElement = Elements.createSpanElement(); Region matchInLine = match.getMatchInLine(); String matchedLine = match.getMatchedLine(); if (matchedLine != null && matchInLine != null) { String startLine = matchedLine.substring(0, matchInLine.getOffset()); textElement.appendChild(Elements.createTextNode(startLine)); SpanElement highlightElement = Elements.createSpanElement(resources.css().searchMatch()); highlightElement .setInnerText(matchedLine.substring(matchInLine.getOffset(), matchInLine.getOffset() + matchInLine.getLength())); textElement.appendChild(highlightElement); textElement.appendChild(Elements.createTextNode(matchedLine.substring(matchInLine.getOffset() + matchInLine.getLength()))); } else { textElement.appendChild(Elements.createTextNode("Can't find sources")); } spanElement.appendChild(textElement); presentation.setPresentableIcon(resources.searchMatch()); presentation.setUserElement((Element)spanElement); } @Override public String getName() { return match.getMatchedLine(); } @Override public boolean isLeaf() { return true; } public Match getMatch() { return match; } @Override public void actionPerformed() { if (compilationUnit != null) { final EditorPartPresenter editorPartPresenter = editorAgent.getOpenedEditor(Path.valueOf(compilationUnit.getPath())); if (editorPartPresenter != null) { selectRange(editorPartPresenter); Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() { @Override public void execute() { editorAgent.activateEditor(editorPartPresenter); } }); return; } appContext.getWorkspaceRoot().getFile(compilationUnit.getPath()).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) { selectRange(editor); } }); } } }); } else if (classFile != null) { final String className = classFile.getElementName(); final Resource resource = appContext.getResource(); if (resource == null) { return; } final Project project = resource.getRelatedProject().get(); service.getContent(project.getLocation(), className) .then(new Operation<ClassContent>() { @Override public void apply(ClassContent content) throws OperationException { final VirtualFile file = new SyntheticFile(Path.valueOf(className.replace('.', '/')).lastSegment(), content.getContent()); editorAgent.openEditor(file, new OpenEditorCallbackImpl() { @Override public void onEditorOpened(EditorPartPresenter editor) { selectRange(editor); } }); } }); } } private void selectRange(EditorPartPresenter editor) { if (editor instanceof TextEditor) { ((TextEditor)editor).getDocument().setSelectedRange( LinearRange.createWithStart(match.getFileMatchRegion().getOffset()).andLength(match.getFileMatchRegion().getLength()), true); } } }