/******************************************************************************* * 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.editor; import com.google.common.base.Strings; import com.google.common.base.Optional; import com.google.gwt.resources.client.ImageResource; import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.AssistedInject; import org.eclipse.che.ide.api.editor.EditorAgent; import org.eclipse.che.ide.api.editor.EditorPartPresenter; import org.eclipse.che.ide.api.icon.Icon; import org.eclipse.che.ide.api.resources.Project; import org.eclipse.che.ide.api.resources.Resource; import org.eclipse.che.ide.api.resources.VirtualFile; 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.refactoring.RefactoringUpdater; import org.eclipse.che.ide.ext.java.shared.dto.ProposalPresentation; import org.eclipse.che.ide.ext.java.shared.dto.Proposals; import org.eclipse.che.ide.api.editor.codeassist.CodeAssistCallback; import org.eclipse.che.ide.api.editor.codeassist.CodeAssistProcessor; import org.eclipse.che.ide.api.editor.codeassist.CompletionProposal; import org.eclipse.che.ide.api.editor.link.HasLinkedMode; import org.eclipse.che.ide.api.editor.texteditor.TextEditor; 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 org.vectomatic.dom.svg.ui.SVGResource; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import static org.eclipse.che.ide.ext.java.client.util.JavaUtil.resolveFQN; public class JavaCodeAssistProcessor implements CodeAssistProcessor { private static Map<String, ImageResource> images; private static Map<String, SVGResource> svgs; private final EditorPartPresenter editor; private final JavaResources resources; private final RefactoringUpdater refactoringUpdater; private final JavaCodeAssistClient client; private final EditorAgent editorAgent; private final DtoUnmarshallerFactory unmarshallerFactory; private final JavaLocalizationConstant localizationConstant; private String errorMessage; @AssistedInject public JavaCodeAssistProcessor(@Assisted final EditorPartPresenter editor, final JavaCodeAssistClient client, final JavaResources javaResources, RefactoringUpdater refactoringUpdater, EditorAgent editorAgent, DtoUnmarshallerFactory unmarshallerFactory, JavaLocalizationConstant localizationConstant) { this.editor = editor; this.client = client; this.resources = javaResources; this.refactoringUpdater = refactoringUpdater; this.editorAgent = editorAgent; this.unmarshallerFactory = unmarshallerFactory; this.localizationConstant = localizationConstant; if (images == null) { initImages(javaResources); } } private void initImages(JavaResources resources) { images = new HashMap<>(); svgs = new HashMap<>(); svgs.put("template", resources.template()); svgs.put("javadoc", resources.javadoc()); svgs.put("annotation", resources.annotationItem()); //todo create images for annotations svgs.put("privateAnnotation", resources.annotationItem()); svgs.put("protectedAnnotation", resources.annotationItem()); svgs.put("defaultAnnotation", resources.annotationItem()); svgs.put("enum", resources.enumItem()); svgs.put("defaultEnum", resources.enumItem()); svgs.put("privateEnum", resources.enumItem()); svgs.put("protectedEnum", resources.enumItem()); svgs.put("interface", resources.interfaceItem()); svgs.put("defaultInterface", resources.interfaceItem()); svgs.put("innerInterfacePublic", resources.interfaceItem()); svgs.put("innerInterfacePrivate", resources.interfaceItem()); svgs.put("innerInterfaceProtected", resources.interfaceItem()); svgs.put("class", resources.svgClassItem()); svgs.put("defaultClass", resources.svgClassItem()); svgs.put("innerClassPrivate", resources.svgClassItem()); svgs.put("innerClassProtected", resources.svgClassItem()); svgs.put("innerClassDefault", resources.svgClassItem()); svgs.put("privateMethod", resources.privateMethod()); svgs.put("publicMethod", resources.publicMethod()); svgs.put("protectedMethod", resources.protectedMethod()); svgs.put("defaultMethod", resources.defaultMethod()); svgs.put("publicField", resources.publicField()); svgs.put("protectedField", resources.protectedField()); svgs.put("privateField", resources.privateField()); svgs.put("defaultField", resources.defaultField()); svgs.put("localVariable", resources.localVar()); svgs.put("package", resources.packageItem()); svgs.put("correctionLocal", resources.correctionChange()); svgs.put("correctionChange", resources.correctionChange()); svgs.put("correctionAdd", resources.correctionChange()); svgs.put("jexception", resources.exceptionProp()); svgs.put("correctionRemove", resources.correctionRemove()); svgs.put("correctionCast", resources.correctionCast()); svgs.put("correctionMove", resources.correctionRemove()); svgs.put("correctionDeleteImport", resources.correctionDeleteImport()); svgs.put("impObj", resources.add()); svgs.put("toolDelete", resources.remove()); svgs.put("linkedRename", resources.linkedRename()); } public static String insertStyle(final JavaResources javaResources, final String display) { if (display.contains("#FQN#")) { return display.replace("#FQN#", javaResources.css().fqnStyle()); } else if (display.contains("#COUNTER#")) { return display.replace("#COUNTER#", javaResources.css().counter()); } else { return display; } } public static Icon getIcon(final String image) { if (svgs.containsKey(image)) { return new Icon("", svgs.get(image)); } return new Icon("", images.get(image)); } @Override public void computeCompletionProposals(final TextEditor textEditor, final int offset, final boolean triggered, final CodeAssistCallback callback) { if (errorMessage != null) { return; } final VirtualFile file = editor.getEditorInput().getFile(); if (file instanceof Resource) { final Optional<Project> project = ((Resource)file).getRelatedProject(); Unmarshallable<Proposals> unmarshaller = unmarshallerFactory.newUnmarshaller(Proposals.class); client.computeProposals(project.get().getLocation().toString(), resolveFQN(file), offset, textEditor.getDocument().getContents(), new AsyncRequestCallback<Proposals>(unmarshaller) { @Override protected void onSuccess(Proposals proposals) { showProposals(callback, proposals); } @Override protected void onFailure(Throwable throwable) { Log.error(JavaCodeAssistProcessor.class, throwable); } }); } } private void showProposals(final CodeAssistCallback callback, final Proposals respons) { List<ProposalPresentation> presentations = respons.getProposals(); final List<CompletionProposal> proposals = new ArrayList<>(presentations.size()); HasLinkedMode linkedEditor = editor instanceof HasLinkedMode ? (HasLinkedMode)editor : null; for (final ProposalPresentation proposal : presentations) { final CompletionProposal completionProposal = new JavaCompletionProposal(proposal.getIndex(), insertStyle(resources, proposal.getDisplayString()), getIcon(proposal.getImage()), client, respons.getSessionId(), linkedEditor, refactoringUpdater, editorAgent); proposals.add(completionProposal); } callback.proposalComputed(proposals); } @Override public String getErrorMessage() { return this.errorMessage; } public void disableCodeAssistant(String errorMessage) { this.errorMessage = Strings.isNullOrEmpty(errorMessage) ? localizationConstant.codeAssistDefaultErrorMessage() : errorMessage; } public void enableCodeAssistant() { this.errorMessage = null; } }