/******************************************************************************* * Copyright (c) 2006, 2007 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.search.internal.queries; import java.util.Iterator; import java.util.regex.Pattern; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.search.ui.ISearchQuery; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.LookupOverride; import org.springframework.beans.factory.support.MethodOverride; import org.springframework.beans.factory.support.ReplaceOverride; import org.springframework.ide.eclipse.beans.core.internal.model.Bean; 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.core.model.IBeanAlias; import org.springframework.ide.eclipse.beans.core.model.IBeanProperty; import org.springframework.ide.eclipse.beans.core.model.IBeanReference; import org.springframework.ide.eclipse.beans.core.model.IBeansList; import org.springframework.ide.eclipse.beans.core.model.IBeansMap; import org.springframework.ide.eclipse.beans.core.model.IBeansMapEntry; import org.springframework.ide.eclipse.beans.core.model.IBeansSet; import org.springframework.ide.eclipse.beans.core.model.IBeansTypedString; import org.springframework.ide.eclipse.beans.core.model.IBeansValueHolder; import org.springframework.ide.eclipse.beans.ui.search.internal.BeansSearchMessages; import org.springframework.ide.eclipse.beans.ui.search.internal.BeansSearchScope; import org.springframework.ide.eclipse.core.MessageUtils; import org.springframework.ide.eclipse.core.model.IModelElement; /** * This {@link ISearchQuery} looks for all {@link IBean}s which are referencing * a given bean. * @author Torsten Juergeleit * @author Christian Dupuis */ public class BeanReferenceQuery extends AbstractBeansQuery { public static final String PROXY_FACTORY_CLASS_NAME = "org.springframework.aop.framework.ProxyFactoryBean"; public BeanReferenceQuery(BeansSearchScope scope, String pattern, boolean isCaseSensitive, boolean isRegexSearch) { super(scope, pattern, isCaseSensitive, isRegexSearch); } public String getLabel() { Object[] args = new Object[] { getPattern(), getScope().getDescription() }; return MessageUtils.format( BeansSearchMessages.SearchQuery_searchFor_reference, args); } @Override protected boolean doesMatch(IModelElement element, Pattern pattern, IProgressMonitor monitor) { if (element instanceof IBeanAlias) { IBeanAlias alias = (IBeanAlias) element; if (pattern.matcher(alias.getBeanName()).matches()) { return true; } } else if (element instanceof IBean) { IBean bean = (IBean) element; // Compare reference with parent bean if (bean.isChildBean() && pattern.matcher(bean.getParentName()).matches()) { return true; } AbstractBeanDefinition bd = (AbstractBeanDefinition) ((Bean) element).getBeanDefinition(); // Compare reference with factory bean String factoryBeanName = bd.getFactoryBeanName(); if (factoryBeanName != null && pattern.matcher(factoryBeanName).matches()) { return true; } // Compare reference with depends-on beans String dependsOnBeanNames[] = bd.getDependsOn(); if (dependsOnBeanNames != null) { for (String name : dependsOnBeanNames) { if (pattern.matcher(name).matches()) { return true; } } } // Compare reference with method-override beans if (!bd.getMethodOverrides().isEmpty()) { Iterator methodsOverrides = bd.getMethodOverrides() .getOverrides().iterator(); while (methodsOverrides.hasNext()) { MethodOverride methodOverride = (MethodOverride) methodsOverrides.next(); if (methodOverride instanceof LookupOverride) { String name = ((LookupOverride) methodOverride) .getBeanName(); if (pattern.matcher(name).matches()) { return true; } } else if (methodOverride instanceof ReplaceOverride) { String name = ((ReplaceOverride) methodOverride) .getMethodReplacerBeanName(); if (pattern.matcher(name).matches()) { return true; } } } } } else if (element instanceof IBeansValueHolder) { return doesValueMatch(element, ((IBeansValueHolder) element) .getValue(), pattern); } return false; } private boolean doesValueMatch(IModelElement element, Object value, Pattern pattern) { if (value instanceof IBeanReference) { String name = ((IBeanReference) value).getBeanName(); if (pattern.matcher(name).matches()) { return true; } } else if (value instanceof IBeansList) { // Compare reference with bean property's interceptors if (element instanceof IBeanProperty && element.getElementName().equals("interceptorNames")) { String beanClass = BeansModelUtils.getBeanClass((IBean) element .getElementParent(), null); if (PROXY_FACTORY_CLASS_NAME.equals(beanClass)) { for (IModelElement child : ((IBeansList) value) .getElementChildren()) { if (child instanceof IBeansTypedString) { if (pattern.matcher(((IBeansTypedString) child) .getString()).matches()) { return true; } } } } } else { for (IModelElement child : ((IBeansList) value) .getElementChildren()) { if (doesValueMatch(element, child, pattern)) { return true; } } } } else if (value instanceof IBeansSet) { for (IModelElement child : ((IBeansSet) value) .getElementChildren()) { if (doesValueMatch(element, child, pattern)) { return true; } } } else if (value instanceof IBeansMap) { for (IModelElement child : ((IBeansMap) value) .getElementChildren()) { if (child instanceof IBeansMapEntry) { if (doesValueMatch(element, ((IBeansMapEntry) child) .getKey(), pattern) || doesValueMatch(element, ((IBeansMapEntry) child) .getValue(), pattern)) { return true; } } } } return false; } }