/*******************************************************************************
* Copyright (c) 2006, 2014 Spring IDE Developers
* 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:
* Spring IDE Developers - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.beans.ui.editor.util;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.Signature;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.springframework.ide.eclipse.beans.core.internal.model.BeansModelUtils;
import org.springframework.ide.eclipse.beans.core.model.IBean;
import org.springframework.ide.eclipse.beans.ui.BeansUIImages;
import org.springframework.ide.eclipse.beans.ui.BeansUIPlugin;
import org.springframework.ide.eclipse.beans.ui.editor.contentassist.IContentAssistProposalRecorder;
import org.springframework.ide.eclipse.beans.ui.editor.outline.DelegatingLabelProvider;
import org.springframework.ide.eclipse.core.java.JdtUtils;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
/**
* Utility class for accepting bean matches and creating completion proposals for those bean matches.
* @author Christian Dupuis
* @author Torsten Juergeleit
* @since 2.0
*/
public class BeanReferenceSearchRequestor {
public static final String LABEL_SEPARATOR = " -------------------------------------------- ";
public static final int TYPE_MATCHING_RELEVANCE = 20;
public static final int RELEVANCE = 10;
protected Set<String> beans;
protected IContentAssistProposalRecorder recorder;
protected List<String> requiredTypes = null;
private boolean insertedMatchingType = false;
private boolean matchingTypeFound = false;
public BeanReferenceSearchRequestor(IContentAssistProposalRecorder recorder) {
this(recorder, new ArrayList<String>());
}
public BeanReferenceSearchRequestor(IContentAssistProposalRecorder recorder, List<String> requiredTypes) {
this.recorder = recorder;
this.beans = new HashSet<String>();
this.requiredTypes = requiredTypes;
}
public void acceptSearchMatch(IBean bean, IFile file, String prefix) {
if (bean.getElementName() != null && bean.getElementName().toLowerCase().startsWith(prefix.toLowerCase())) {
String beanName = bean.getElementName();
String replaceText = beanName;
String fileName = bean.getElementResource().getProjectRelativePath().toString();
String key = beanName + fileName;
if (!beans.contains(key)) {
StringBuffer buf = new StringBuffer();
buf.append(beanName);
if (bean.getClassName() != null) {
String className = bean.getClassName();
buf.append(" [");
buf.append(Signature.getSimpleName(className));
buf.append("]");
}
if (bean.getParentName() != null) {
buf.append(" <");
buf.append(bean.getParentName());
buf.append(">");
}
buf.append(" - ");
buf.append(fileName);
String displayText = buf.toString();
Image image = null;
if (Display.getCurrent() != null) {
image = BeansUIPlugin.getLabelProvider().getImage(bean);
}
boolean matchesType = false;
if (requiredTypes.size() > 0) {
String className = BeansModelUtils.getBeanClass(bean, null);
IType type = JdtUtils.getJavaType(file.getProject(), className);
List<String> hierachyTypes = JdtUtils.getFlatListOfClassAndInterfaceNames(type, type);
for (String cn : hierachyTypes) {
if (this.requiredTypes.contains(cn)) {
matchesType = true;
break;
}
}
}
if (!insertedMatchingType && matchingTypeFound && !matchesType) {
recorder.recordProposal(BeansUIImages.getImage(BeansUIImages.IMG_OBJS_CONTENT_ASSIST),
TYPE_MATCHING_RELEVANCE - 1, LABEL_SEPARATOR, "");
insertedMatchingType = true;
}
if (matchesType) {
recorder.recordProposal(image, TYPE_MATCHING_RELEVANCE, displayText, replaceText, null);
matchingTypeFound = true;
}
else {
recorder.recordProposal(image, RELEVANCE, displayText, replaceText, bean);
}
beans.add(key);
}
}
}
public void acceptSearchMatch(String beanId, Node beanNode, IFile file, String prefix) {
if (beanNode != null) {
NamedNodeMap attributes = beanNode.getAttributes();
if (beanId.toLowerCase().startsWith(prefix.toLowerCase())) {
if (beanNode.getParentNode() != null) {
String beanName = beanId;
String replaceText = beanName;
String fileName = file.getProjectRelativePath().toString();
String key = beanName + fileName;
if (!beans.contains(key)) {
StringBuffer buf = new StringBuffer();
buf.append(beanName);
if (attributes.getNamedItem("class") != null) {
String className = attributes.getNamedItem("class").getNodeValue();
buf.append(" [");
buf.append(Signature.getSimpleName(className));
buf.append("]");
}
if (attributes.getNamedItem("parent") != null) {
String parentName = attributes.getNamedItem("parent").getNodeValue();
buf.append(" <");
buf.append(parentName);
buf.append(">");
}
buf.append(" - ");
buf.append(fileName);
String displayText = buf.toString();
Image image = null;
if (Display.getCurrent() != null) {
image = new DelegatingLabelProvider().getImage(beanNode);
}
String className = BeansEditorUtils.getClassNameForBean(beanNode);
boolean matchesType = false;
if (requiredTypes.size() > 0) {
IType type = JdtUtils.getJavaType(file.getProject(), className);
List<String> hierachyTypes = JdtUtils.getFlatListOfClassAndInterfaceNames(type, type);
for (String cn : hierachyTypes) {
if (this.requiredTypes.contains(cn)) {
matchesType = true;
break;
}
}
}
if (!insertedMatchingType && matchingTypeFound && !matchesType) {
recorder.recordProposal(BeansUIImages.getImage(BeansUIImages.IMG_OBJS_CONTENT_ASSIST),
TYPE_MATCHING_RELEVANCE - 1, LABEL_SEPARATOR, "");
insertedMatchingType = true;
}
if (matchesType) {
recorder.recordProposal(image, TYPE_MATCHING_RELEVANCE, displayText, replaceText, beanNode);
matchingTypeFound = true;
}
else {
recorder.recordProposal(image, RELEVANCE, displayText, replaceText, beanNode);
}
beans.add(key);
}
}
}
}
}
}