/*******************************************************************************
* 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.worker;
import org.eclipse.che.ide.collections.Array;
import org.eclipse.che.ide.collections.js.JsoArray;
import org.eclipse.che.ide.collections.js.JsoStringMap;
import org.eclipse.che.ide.ext.java.jdt.MultiStatus;
import org.eclipse.che.ide.ext.java.jdt.codeassistant.api.IProblemLocation;
import org.eclipse.che.ide.ext.java.jdt.codeassistant.api.JavaCompletionProposal;
import org.eclipse.che.ide.ext.java.jdt.core.JavaCore;
import org.eclipse.che.ide.ext.java.jdt.core.dom.CompilationUnit;
import org.eclipse.che.ide.ext.java.jdt.internal.text.correction.AdvancedQuickAssistProcessor;
import org.eclipse.che.ide.ext.java.jdt.internal.text.correction.AssistContext;
import org.eclipse.che.ide.ext.java.jdt.internal.text.correction.CorrectionMessages;
import org.eclipse.che.ide.ext.java.jdt.internal.text.correction.ProblemLocation;
import org.eclipse.che.ide.ext.java.jdt.internal.text.correction.QuickAssistProcessorImpl;
import org.eclipse.che.ide.ext.java.jdt.internal.text.correction.QuickFixProcessorImpl;
import org.eclipse.che.ide.ext.java.jdt.quickassist.api.InvocationContext;
import org.eclipse.che.ide.ext.java.jdt.quickassist.api.QuickAssistProcessor;
import org.eclipse.che.ide.ext.java.jdt.quickassist.api.QuickFixProcessor;
import org.eclipse.che.ide.ext.java.messages.ComputeCorrMessage;
import org.eclipse.che.ide.ext.java.messages.ProblemLocationMessage;
import org.eclipse.che.ide.ext.java.messages.RoutingTypes;
import org.eclipse.che.ide.ext.java.messages.WorkerProposal;
import org.eclipse.che.ide.ext.java.messages.impl.MessagesImpls;
import org.eclipse.che.ide.runtime.CoreException;
import org.eclipse.che.ide.runtime.IStatus;
import org.eclipse.che.ide.runtime.Status;
import org.eclipse.che.ide.util.UUID;
import com.google.gwt.webworker.client.messages.MessageFilter;
import java.util.ArrayList;
import java.util.Collection;
/**
* WorkerCorrectionProcessor
*
* @author Evgen Vidolob
*/
public class WorkerCorrectionProcessor {
private static QuickFixProcessor fixProcessor = new QuickFixProcessorImpl();
private static QuickAssistProcessor[] assistProcessors =
new QuickAssistProcessor[]{new QuickAssistProcessorImpl(), new AdvancedQuickAssistProcessor()};
private String fErrorMessage;
private JavaParserWorker worker;
private WorkerProposalApplier workerProposalApplier;
private WorkerCuCache cuCache;
public WorkerCorrectionProcessor(JavaParserWorker worker, MessageFilter messageFilter, WorkerProposalApplier workerProposalApplier,
WorkerCuCache cuCache) {
this.worker = worker;
this.workerProposalApplier = workerProposalApplier;
this.cuCache = cuCache;
messageFilter.registerMessageRecipient(RoutingTypes.COMPUTE_CORRECTION, new MessageFilter.MessageRecipient<ComputeCorrMessage>() {
@Override
public void onMessageReceived(ComputeCorrMessage message) {
computateProposals(message);
}
});
}
public static IStatus collectProposals(InvocationContext context,
Array<ProblemLocationMessage> plMessage, boolean addQuickFixes, boolean addQuickAssists,
Collection<JavaCompletionProposal> proposals)
throws CoreException {
ProblemLocation[] problemLocations = new ProblemLocation[plMessage.size()];
for (int i = 0; i < plMessage.size(); i++) {
problemLocations[i] = new ProblemLocation(plMessage.get(i));
}
// ProblemLocation[] problems = problems.toArray(new ProblemLocation[problems.size()]);
MultiStatus resStatus = null;
//
if (addQuickFixes) {
IStatus status = collectCorrections(context, problemLocations, proposals);
if (!status.isOK()) {
resStatus =
new MultiStatus(JavaCore.PLUGIN_ID, IStatus.ERROR,
CorrectionMessages.INSTANCE.JavaCorrectionProcessor_error_quickfix_message(), null);
resStatus.add(status);
}
}
if (addQuickAssists) {
IStatus status = collectAssists(context, problemLocations, proposals);
if (!status.isOK()) {
if (resStatus == null) {
resStatus =
new MultiStatus(JavaCore.PLUGIN_ID, IStatus.ERROR,
CorrectionMessages.INSTANCE.JavaCorrectionProcessor_error_quickassist_message(), null);
}
resStatus.add(status);
}
}
if (resStatus != null) {
return resStatus;
}
return Status.OK_STATUS;
}
public static IStatus collectAssists(InvocationContext context, IProblemLocation[] locations,
Collection<JavaCompletionProposal> proposals) throws CoreException {
for (QuickAssistProcessor curr : assistProcessors) {
JavaCompletionProposal[] res;
res = curr.getAssists(context, locations);
if (res != null) {
for (int k = 0; k < res.length; k++) {
proposals.add(res[k]);
}
}
}
return Status.OK_STATUS;
}
public static IStatus collectCorrections(InvocationContext context, IProblemLocation[] locations,
Collection<JavaCompletionProposal> proposals) throws CoreException {
JavaCompletionProposal[] res;
res = fixProcessor.getCorrections(context, locations);
if (res != null) {
for (int k = 0; k < res.length; k++) {
proposals.add(res[k]);
}
}
return Status.OK_STATUS;
}
public static boolean hasAssists(InvocationContext context) {
for (QuickAssistProcessor curr : assistProcessors) {
try {
if (curr.hasAssists(context))
return true;
} catch (CoreException e) {
// Log.error(WorkerCorrectionProcessor.class, e);
return false;
}
}
return false;
}
// public void setCu(CompilationUnit cu) {
// this.cu = cu;
// }
public void computateProposals(ComputeCorrMessage message) {
JsoStringMap<JavaCompletionProposal> proposalMap = JsoStringMap.create();
int documentOffset = message.documentOffset();
WorkerDocument document = new WorkerDocument(message.documentContent());
AssistContext context = null;
CompilationUnit cu = cuCache.getCompilationUnit(message.filePath());
if (cu != null) {
int length = message.documentSelectionLength();
context = new AssistContext(document, documentOffset, length, cu);
}
fErrorMessage = null;
Array<ProblemLocationMessage> problemLocations = message.problemLocations();
ArrayList<JavaCompletionProposal> proposals = new ArrayList<JavaCompletionProposal>(10);
try {
if (context != null && problemLocations != null) {
IStatus status =
collectProposals(context, problemLocations, true, !message.updatedOffset(), proposals);
if (!status.isOK()) {
fErrorMessage = status.getMessage();
//TODO
//JavaPlugin.log(status);
}
}
} catch (CoreException e) {
//TODO log error
throw new RuntimeException(e);
}
MessagesImpls.CAProposalsComputedMessageImpl caComputedMessage = MessagesImpls.CAProposalsComputedMessageImpl.make();
caComputedMessage.setId(message.id());
JsoArray<WorkerProposal> workerProposals = JsoArray.create();
for (JavaCompletionProposal proposal : proposals) {
MessagesImpls.WorkerProposalImpl prop = MessagesImpls.WorkerProposalImpl.make();
prop.setAutoInsertable(proposal.isAutoInsertable()).setDisplayText(proposal.getDisplayString())
.setImage(proposal.getImage() == null ? null : proposal.getImage().name());
String uuid = UUID.uuid();
prop.setId(uuid);
proposalMap.put(uuid, proposal);
workerProposals.add(prop);
}
workerProposalApplier.setQuickDocument(document);
workerProposalApplier.setQuickProposalMap(proposalMap);
caComputedMessage.setProposals(workerProposals);
worker.sendMessage(caComputedMessage.serialize());
}
public static boolean hasCorrections(IProblemLocation annot) {
return fixProcessor.hasCorrections(annot.getProblemId());
}
}