/******************************************************************************* * 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.gwt.user.client.rpc.AsyncCallback; import com.google.inject.Inject; import com.google.inject.Singleton; import org.eclipse.che.api.promises.client.Function; import org.eclipse.che.api.promises.client.FunctionException; import org.eclipse.che.api.promises.client.Promise; import org.eclipse.che.ide.MimeType; import org.eclipse.che.ide.api.app.AppContext; import org.eclipse.che.ide.api.machine.WsAgentURLModifier; import org.eclipse.che.ide.ext.java.shared.dto.Change; import org.eclipse.che.ide.ext.java.shared.dto.ConflictImportDTO; import org.eclipse.che.ide.ext.java.shared.dto.OrganizeImportResult; import org.eclipse.che.ide.ext.java.shared.dto.Problem; import org.eclipse.che.ide.ext.java.shared.dto.ProposalApplyResult; import org.eclipse.che.ide.ext.java.shared.dto.Proposals; import org.eclipse.che.ide.rest.AsyncRequestCallback; import org.eclipse.che.ide.rest.AsyncRequestFactory; import org.eclipse.che.ide.rest.DtoUnmarshallerFactory; import org.eclipse.che.ide.rest.Unmarshallable; import org.eclipse.che.ide.ui.loaders.request.LoaderFactory; import org.eclipse.che.ide.ui.loaders.request.MessageLoader; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import static org.eclipse.che.ide.rest.HTTPHeader.CONTENT_TYPE; /** * @author Evgen Vidolob */ @Singleton public class JavaCodeAssistClient { private final static String CODE_ASSIST_URL_PREFIX = "/java/code-assist"; private final DtoUnmarshallerFactory unmarshallerFactory; private final AsyncRequestFactory asyncRequestFactory; private final MessageLoader loader; private final AppContext appContext; private final WsAgentURLModifier urlDecorator; @Inject public JavaCodeAssistClient(DtoUnmarshallerFactory unmarshallerFactory, AppContext appContext, LoaderFactory loaderFactory, AsyncRequestFactory asyncRequestFactory, WsAgentURLModifier urlDecorator) { this.appContext = appContext; this.unmarshallerFactory = unmarshallerFactory; this.loader = loaderFactory.newLoader(); this.asyncRequestFactory = asyncRequestFactory; this.urlDecorator = urlDecorator; } public void computeProposals(String projectPath, String fqn, int offset, String contents, AsyncRequestCallback<Proposals> callback) { String url = appContext.getDevMachine().getWsAgentBaseUrl() + CODE_ASSIST_URL_PREFIX + "/compute/completion" + "/?projectpath=" + projectPath + "&fqn=" + fqn + "&offset=" + offset; asyncRequestFactory.createPostRequest(url, null).data(contents).send(callback); } public void computeAssistProposals(String projectPath, String fqn, int offset, List<Problem> problems, AsyncRequestCallback<Proposals> callback) { String url = appContext.getDevMachine().getWsAgentBaseUrl() + CODE_ASSIST_URL_PREFIX + "/compute/assist" + "/?projectpath=" + projectPath + "&fqn=" + fqn + "&offset=" + offset; List<Problem> prob = new ArrayList<>(); prob.addAll(problems); asyncRequestFactory.createPostRequest(url, prob).send(callback); } public void applyProposal(String sessionId, int index, boolean insert, final AsyncCallback<ProposalApplyResult> callback) { String url = appContext.getDevMachine().getWsAgentBaseUrl() + CODE_ASSIST_URL_PREFIX + "/apply/completion/?sessionid=" + sessionId + "&index=" + index + "&insert=" + insert; Unmarshallable<ProposalApplyResult> unmarshaller = unmarshallerFactory.newUnmarshaller(ProposalApplyResult.class); asyncRequestFactory.createGetRequest(url).send(new AsyncRequestCallback<ProposalApplyResult>(unmarshaller) { @Override protected void onSuccess(ProposalApplyResult proposalApplyResult) { callback.onSuccess(proposalApplyResult); } @Override protected void onFailure(Throwable throwable) { callback.onFailure(throwable); } }); } public String getProposalDocUrl(int id, String sessionId) { return urlDecorator.modify(appContext.getDevMachine().getWsAgentBaseUrl() + CODE_ASSIST_URL_PREFIX + "/compute/info?sessionid=" + sessionId + "&index=" + id); } /** * Creates edits that describe how to format the given string. * Returns the changes required to format source. * Note: Java code formatting is supported only. * * @param offset * The given offset to start recording the edits (inclusive). * @param length * the given length to stop recording the edits (exclusive). * @param content * the content to format */ public Promise<List<Change>> format(final int offset, final int length, final String content) { return getFormatChanges(offset, length, content).then(new Function<List<Change>, List<Change>>() { @Override public List<Change> apply(List<Change> arg) throws FunctionException { return arg.stream().collect(Collectors.toList()); } }); } private Promise<List<Change>> getFormatChanges(final int offset, final int length, final String content) { final String baseUrl = appContext.getDevMachine().getWsAgentBaseUrl(); final String url = baseUrl + CODE_ASSIST_URL_PREFIX + "/format?offset=" + offset + "&length=" + length; return asyncRequestFactory.createPostRequest(url, null) .header(CONTENT_TYPE, MimeType.TEXT_PLAIN) .data(content) .send(unmarshallerFactory.newListUnmarshaller(Change.class)); } /** * Organizes the imports of a compilation unit. * * @param projectPath * path to the project * @param fqn * fully qualified name of the java file * @return list of imports which have conflicts */ public Promise<OrganizeImportResult> organizeImports(String projectPath, String fqn) { String url = appContext.getDevMachine().getWsAgentBaseUrl() + CODE_ASSIST_URL_PREFIX + "/organize-imports?projectpath=" + projectPath + "&fqn=" + fqn; return asyncRequestFactory.createPostRequest(url, null) .loader(loader) .send(unmarshallerFactory.newUnmarshaller(OrganizeImportResult.class)); } /** * Organizes the imports of a compilation unit. * * @param projectPath * path to the project * @param fqn * fully qualified name of the java file */ public Promise<List<Change>> applyChosenImports(String projectPath, String fqn, ConflictImportDTO chosen) { String url = appContext.getDevMachine().getWsAgentBaseUrl() + CODE_ASSIST_URL_PREFIX + "/apply-imports?projectpath=" + projectPath + "&fqn=" + fqn; return asyncRequestFactory.createPostRequest(url, chosen) .loader(loader) .header(CONTENT_TYPE, MimeType.APPLICATION_JSON) .send(unmarshallerFactory.newListUnmarshaller(Change.class)); } }