/*
* Copyright 2013 Hewlett-Packard Development Company, L.P
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hp.alm.ali.idea.navigation.recognizer;
import com.hp.alm.ali.idea.entity.EntityQuery;
import com.hp.alm.ali.idea.navigation.Recognizer;
import com.hp.alm.ali.idea.util.EditSourceUtil;
import com.hp.alm.ali.idea.util.FileEditorManager;
import com.intellij.navigation.ChooseByNameContributor;
import com.intellij.navigation.ChooseByNameRegistry;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiBundle;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import java.util.HashMap;
import java.util.Map;
public abstract class ClassRecognizer implements Recognizer {
public boolean navigate(Project project, String hyperlink) {
if(hyperlink.startsWith("goto:")) {
openEditor(project, hyperlink.substring(5));
return true;
} else {
return false;
}
}
private static Editor openEditor(Project project, String link) {
return evaluate(project, link, true);
}
private static Editor evaluate(Project project, String link, boolean navigate) {
Map<String, String> query = parseQuery(link);
String className = query.get("c");
int line = query.containsKey("l")? Integer.valueOf(query.get("l")): 0;
String file = query.get("f");
String methodName = query.get("m");
for(ChooseByNameContributor contributor: ChooseByNameRegistry.getInstance().getClassModelContributors()) {
NavigationItem[] byName = contributor.getItemsByName(file, file, project, true);
NavigationItem item = matchClass(byName, className);
if(item != null) {
if(!navigate) {
return null;
}
if(item instanceof PsiClass && methodName != null) {
for(PsiMethod method: ((PsiClass)item).getMethods()) {
if(method.getName().equals(methodName)) {
project.getComponent(EditSourceUtil.class).navigate(method, true, true);
return project.getComponent(FileEditorManager.class).getSelectedTextEditor();
}
}
}
project.getComponent(EditSourceUtil.class).navigate(item, true, true);
Editor editor = project.getComponent(FileEditorManager.class).getSelectedTextEditor();
if(line > 0) {
if(editor != null /* && !editor.getDocument().getText().startsWith(PsiBundle.message("psi.decompiled.text.header")) */) { // TODO: string missing since commit 02ca2bd104e91420543cf8c19b2c6a9cbb6c5ab7
editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(line - 1, 0));
editor.getScrollingModel().scrollToCaret(ScrollType.CENTER);
editor.getSelectionModel().removeSelection();
}
}
return editor;
}
}
return null;
}
private static Map<String, String> parseQuery(String query) {
Map<String, String> ret = new HashMap<String, String>();
for(String pair: query.split("&")) {
int p = pair.indexOf('=');
ret.put(pair.substring(0, p), EntityQuery.decode(pair.substring(p + 1)));
}
return ret;
}
private static NavigationItem matchClass(NavigationItem[] items, String className) {
for(NavigationItem item: items) {
if(item instanceof PsiClass) {
if(className.equals(((PsiClass) item).getQualifiedName())) {
return item;
}
}
}
if(items.length > 0) {
return items[0];
} else {
return null;
}
}
}