package org.maziarz.yiiclipse.hyperlinks;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.dltk.ast.ASTVisitor;
import org.eclipse.dltk.ast.declarations.ModuleDeclaration;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.SourceParserUtil;
import org.eclipse.dltk.internal.ui.editor.ModelElementHyperlink;
import org.eclipse.dltk.ui.actions.OpenAction;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector;
import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.php.internal.core.filenetwork.FileNetworkUtility;
import org.eclipse.php.internal.ui.editor.PHPStructuredEditor;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.maziarz.yiiclipse.YiiclipseBundle;
import org.maziarz.yiiclipse.utils.YiiPathResolver;
public class YiiHyperlinkDetector extends AbstractHyperlinkDetector {
@Override
public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) {
PHPStructuredEditor editor = findPhpEditor(textViewer);
if (editor == null) {
YiiclipseBundle.debug("Cannot find file php editor instance.");
return null;
}
IModelElement input = org.eclipse.dltk.internal.ui.editor.EditorUtility.getEditorInputModelElement(editor, false);
if (!(input instanceof ISourceModule)) {
YiiclipseBundle.debug("Cannot find source module input.");
return null;
}
final int offset = region.getOffset();
String[] file = new String[1];
Region[] selectRegion = new Region[1];
final ISourceModule sourceModule = (ISourceModule) input;
ModuleDeclaration moduleDeclaration = SourceParserUtil.getModuleDeclaration(sourceModule, null);
YiiPathResolver pathResolver = new YiiPathResolver(new WorkspacePathHelper());
ASTVisitor visitor = new YiiHyperlinkASTVisitor2(sourceModule, pathResolver, offset, file[0], selectRegion[0]);
try {
moduleDeclaration.traverse(visitor);
} catch (Exception e) {
YiiclipseBundle.logError(e.getMessage(), e);
}
file[0] = ((YiiHyperlinkASTVisitor2)visitor).getFile();
if (file[0]!=null){
YiiclipseBundle.debug("Expected location: "+file[0]);
}
selectRegion[0] = ((YiiHyperlinkASTVisitor2)visitor).getSelectRegion();
if (file[0] != null){
if (file[0].endsWith("css")){
IPath localPath = new Path(file[0]);
IHyperlink hyperlink = new EFSResourceHyperlink(selectRegion[0], localPath);
return new IHyperlink[] {hyperlink};
}
}
ISourceModule viewSourceModule = FileNetworkUtility.findSourceModule(sourceModule, file[0]);
if (viewSourceModule != null) {
IHyperlink hyperlink = new ModelElementHyperlink(selectRegion[0], viewSourceModule, new OpenAction(editor));
return new IHyperlink[] { hyperlink };
} else {
IPath localPath = new Path(file[0]);
if (localPath.toFile().exists()){
// file is most probably external (out of current workspace)
IHyperlink hyperlink = new ExternalResourceHyperlink(selectRegion[0], localPath, editor);
return new IHyperlink[] { hyperlink };
} else {
IFile localFile = ResourcesPlugin.getWorkspace().getRoot().getFile(localPath);
if (localFile.exists()) {
ISourceModule widgetSourceModule = (ISourceModule) DLTKCore.create(localFile);
IHyperlink hyperlink = new ModelElementHyperlink(selectRegion[0], widgetSourceModule, new OpenAction(editor));
return new IHyperlink[] { hyperlink };
} else {
YiiclipseBundle.logWarning("File does not exists: "+localFile.toString());
}
}
}
return null;
}
private PHPStructuredEditor findPhpEditor(final ITextViewer textViewer) {
IWorkbenchPage workbenchpage = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow().getActivePage();
// Check active editor, first:
IEditorPart activeEditorPart = workbenchpage.getActiveEditor();
if (activeEditorPart instanceof PHPStructuredEditor
&& ((PHPStructuredEditor) activeEditorPart).getTextViewer()
.getDocument() == textViewer.getDocument()) {
return (PHPStructuredEditor)activeEditorPart;
}
// Check other editors:
IEditorReference[] editorReferences = workbenchpage
.getEditorReferences();
for (int i = 0; i < editorReferences.length; i++) {
IEditorReference editorReference = editorReferences[i];
IEditorPart editorPart = editorReference.getEditor(false);
if (activeEditorPart != editorPart && (editorPart instanceof PHPStructuredEditor
&& ((PHPStructuredEditor) activeEditorPart).getTextViewer()
.getDocument() == textViewer.getDocument())) {
return (PHPStructuredEditor)editorPart;
}
}
return null;
}
}