/** * Copyright (c) 2010 Darmstadt University of Technology. * 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: * Johannes Lerch - initial API and implementation. */ package org.eclipse.recommenders.internal.calls.rcp.templates; import static org.eclipse.recommenders.internal.calls.rcp.l10n.LogMessages.*; import static org.eclipse.recommenders.utils.Logs.log; import java.util.HashSet; import java.util.List; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.internal.codeassist.complete.CompletionOnSingleNameReference; import org.eclipse.jdt.internal.compiler.ast.ASTNode; import org.eclipse.jdt.internal.corext.template.java.AbstractJavaContextType; import org.eclipse.jdt.internal.corext.template.java.JavaContext; import org.eclipse.jdt.internal.corext.template.java.JavaContextType; import org.eclipse.jdt.internal.ui.JavaPlugin; import org.eclipse.jdt.ui.text.java.JavaContentAssistInvocationContext; import org.eclipse.jface.text.Region; import org.eclipse.jface.text.templates.Template; import org.eclipse.recommenders.completion.rcp.IRecommendersCompletionContext; import org.eclipse.recommenders.rcp.JavaElementResolver; import org.eclipse.recommenders.utils.Recommendations; import org.eclipse.recommenders.utils.names.IMethodName; import org.eclipse.recommenders.utils.names.ITypeName; import org.eclipse.swt.graphics.Image; import com.google.common.collect.Lists; import com.google.common.collect.Sets; @SuppressWarnings("restriction") public class ProposalBuilder { private List<PatternRecommendation> patterns = Lists.newLinkedList(); private Image icon; private IRecommendersCompletionContext rCtx; private JavaContext documentContext; private JavaElementResolver resolver; private String variableName; public ProposalBuilder(Image icon, IRecommendersCompletionContext rCtx, JavaElementResolver resolver, String variableName) { this.icon = icon; this.rCtx = rCtx; this.resolver = resolver; this.variableName = variableName; createDocumentContext(); } private void createDocumentContext() { JavaPlugin plugin = JavaPlugin.getDefault(); if (plugin != null) { AbstractJavaContextType type = (AbstractJavaContextType) plugin.getTemplateContextRegistry() .getContextType(JavaContextType.ID_ALL); JavaContentAssistInvocationContext javaContext = rCtx.getJavaContext(); Region region = rCtx.getReplacementRange(); int offset = 0; ASTNode node = rCtx.getCompletionNode().orNull(); if (node instanceof CompletionOnSingleNameReference) { offset = region.getOffset() - rCtx.getPrefix().length(); } else { offset = region.getOffset() - variableName.length(); } int length = Math.max(0, region.getLength() - 1); documentContext = new JavaContext(type, javaContext.getDocument(), offset, length, rCtx.getCompilationUnit()); documentContext.setForceEvaluation(true); } else { throw new IllegalStateException("No default JavaPlugin found."); //$NON-NLS-1$ } } public void addPattern(PatternRecommendation pattern) { patterns.add(pattern); } public List<JavaTemplateProposal> createProposals() { // 1. sort the most likely patterns on top: patterns = Recommendations.sortByRelevance(patterns); // 2. get rid of duplicates: yes, this happens! HashSet<PatternRecommendation> noDuplicates = Sets.newHashSet(patterns); List<JavaTemplateProposal> result = Lists.newLinkedList(); for (PatternRecommendation pattern : noDuplicates) { try { result.add(new JavaTemplateProposal(createTemplate(pattern), documentContext, icon, pattern)); } catch (Exception e) { log(ERROR_FAILED_TO_CREATE_PROPOSALS, e); } } return result; } private Template createTemplate(PatternRecommendation pattern) { String code = createTemplateCode(pattern); return new Template(pattern.getName(), pattern.getType().getClassName(), "java", code, false); //$NON-NLS-1$ } private String createTemplateCode(PatternRecommendation pattern) { TemplateBuilder tb = new TemplateBuilder(); String receiverName = variableName; for (IMethodName method : pattern.getProposal()) { if (method.isInit()) { receiverName = tb.appendCtor(method, lookupArgumentNames(method)); tb.nl(); } else { tb.appendCall(method, receiverName, lookupArgumentNames(method)); tb.nl(); } } tb.cursor(); return tb.toString(); } private String[] lookupArgumentNames(IMethodName method) { IMethod jdtMethod = resolver.toJdtMethod(method).orNull(); try { if (jdtMethod != null) { return jdtMethod.getParameterNames(); } } catch (JavaModelException e) { log(ERROR_FAILED_TO_FIND_ARGUMENTS_FOR_METHODS, e, jdtMethod); } ITypeName[] parameterTypes = method.getParameterTypes(); String[] parameterNames = new String[parameterTypes.length]; for (int i = 0; i < parameterNames.length; i++) { parameterNames[i] = "arg" + i; //$NON-NLS-1$ } return parameterNames; } }