/*******************************************************************************
* Copyright (c) 2012 VMWare, Inc.
* 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:
* VMWare, Inc. - initial API and implementation
*******************************************************************************/
package org.grails.ide.eclipse.search.controller;
import org.codehaus.groovy.ast.expr.Expression;
import org.codehaus.groovy.ast.expr.MethodCallExpression;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.ui.search.ElementQuerySpecification;
import org.eclipse.jdt.ui.search.ISearchRequestor;
import org.eclipse.jdt.ui.search.QuerySpecification;
import org.grails.ide.eclipse.core.GrailsCoreActivator;
import org.grails.ide.eclipse.editor.groovy.elements.ControllerClass;
import org.grails.ide.eclipse.editor.groovy.elements.GrailsProject;
import org.grails.ide.eclipse.editor.groovy.elements.GrailsWorkspaceCore;
import org.grails.ide.eclipse.search.AbstractGrailsSearch;
import org.grails.ide.eclipse.search.FileSearcher;
import org.grails.ide.eclipse.search.GSPSearcher;
import org.grails.ide.eclipse.search.SearchUtil;
import org.grails.ide.eclipse.search.SearchingCodeVisitor;
/**
* Searches for controller references inside a Grails project.
*
* @author Kris De Volder
*
* @since 2.9
*/
public class ControllerTypeSearch extends AbstractGrailsSearch {
/**
* The logical (i.e. lower-cased, unquallifed name of the controller being searched for.
*/
private String targetControllerName;
public ControllerTypeSearch(QuerySpecification specification) {
if (specification instanceof ElementQuerySpecification) {
ElementQuerySpecification spec = (ElementQuerySpecification) specification;
if (SearchUtil.wantsReferences(spec)) {
IJavaSearchScope scope = spec.getScope();
IJavaElement el = spec.getElement();
if (el.getElementType()==IJavaElement.TYPE) {
IType targetType = (IType) el;
IJavaProject project = targetType.getJavaProject();
if (project!=null) {
GrailsProject grailsProject = GrailsWorkspaceCore.get().create(project);
if (grailsProject!=null) {
ControllerClass targetController = grailsProject.getControllerClass(targetType);
if (targetController!=null) {
init(grailsProject, targetController.getLogicalName(), scope);
}
}
}
}
}
}
}
private void init(GrailsProject grailsProject, String controllerName, IJavaSearchScope scope) {
this.targetControllerName = controllerName;
addControllersFrom(grailsProject.getJavaProject(), scope);
addGspFilesFrom(grailsProject, scope);
addUrlMappingsFrom(grailsProject, scope);
}
public ControllerTypeSearch(GrailsProject grailsProject, String targetControllerName) {
init(grailsProject, targetControllerName, null);
}
public SearchingCodeVisitor createSearchingVisitor(ISearchRequestor requestor, ICompilationUnit cu) {
return new ControllerReferenceSearchingVisitor(cu, requestor);
}
@Override
protected GSPSearcher createGSPSearcher(ISearchRequestor requestor, IFile gspFile) {
return new GSPControllerTypeSearcher(gspFile, targetControllerName, requestor);
}
@Override
protected FileSearcher createURLMappingSearcher(ISearchRequestor requestor, IFile urlMappingsFile) {
return new URLMappingControllerTypeSearcher(requestor, targetControllerName, urlMappingsFile);
}
public class ControllerReferenceSearchingVisitor extends SearchingCodeVisitor {
public ISearchRequestor javaRequestor;
public ControllerReferenceSearchingVisitor(ICompilationUnit cu, ISearchRequestor requestor) {
super(cu);
this.javaRequestor = requestor;
}
@Override
protected SearchingCodeVisitor.MethodCallAction getMethodCallAction(String methodName) {
if (methodName!=null) {
if (methodName.equals("redirect")) {
return new SearchRedirectCall();
}
}
return null;
}
public class SearchRedirectCall extends SearchingCodeVisitor.FindNamedArgumentAction {
public SearchRedirectCall() {
super("redirect", "controller", targetControllerName);
}
@Override
protected void matchFound(SearchingCodeVisitor visitor, MethodCallExpression call, Expression valueExpression) {
try {
javaRequestor.reportMatch(createMatch(valueExpression, oldValue));
} catch (CoreException e) {
GrailsCoreActivator.log(e);
}
}
}
}
}