package org.rubypeople.rdt.internal.debug.ui; import java.io.File; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.model.IPersistableSourceLocator; import org.eclipse.debug.core.model.IStackFrame; import org.eclipse.debug.ui.ISourcePresentation; import org.eclipse.ui.IEditorDescriptor; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.PartInitException; import org.eclipse.ui.ide.IDE; import org.eclipse.ui.part.FileEditorInput; import org.rubypeople.rdt.debug.core.RdtDebugCorePlugin; import org.rubypeople.rdt.debug.core.model.IRubyStackFrame; import org.rubypeople.rdt.internal.ui.rubyeditor.ExternalRubyFileEditorInput; import org.rubypeople.rdt.launching.IRubyLaunchConfigurationConstants; import org.rubypeople.rdt.ui.RubyUI; /** * @author Administrator To change this generated comment edit the template variable "typecomment": * Window>Preferences>Java>Templates. To enable and disable the creation of type comments go to * Window>Preferences>Java>Code Generation. */ public class RubySourceLocator implements IPersistableSourceLocator, ISourcePresentation { private String absoluteWorkingDirectory; private String projectName; public RubySourceLocator() { } public String getAbsoluteWorkingDirectory() { return absoluteWorkingDirectory; } /** * @see org.eclipse.debug.core.model.IPersistableSourceLocator#getMemento() */ public String getMemento() throws CoreException { return null; } /** * @see org.eclipse.debug.core.model.IPersistableSourceLocator#initializeFromMemento(String) */ public void initializeFromMemento(String memento) throws CoreException { } /** * @see org.eclipse.debug.core.model.IPersistableSourceLocator#initializeDefaults(ILaunchConfiguration) */ public void initializeDefaults(ILaunchConfiguration configuration) throws CoreException { this.absoluteWorkingDirectory = configuration.getAttribute( IRubyLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, ""); //$NON-NLS-1$ this.projectName = configuration.getAttribute(IRubyLaunchConfigurationConstants.ATTR_PROJECT_NAME, ""); //$NON-NLS-1$ } /** * @see org.eclipse.debug.core.model.ISourceLocator#getSourceElement(IStackFrame) */ public Object getSourceElement(IStackFrame stackFrame) { return this.getSourceElement(((IRubyStackFrame) stackFrame).getFileName()); } public Object getSourceElement(String pFilename) { return new SourceElement(pFilename, this); } /** * @see org.eclipse.debug.ui.ISourcePresentation#getEditorId(IEditorInput, Object) */ public String getEditorId(IEditorInput input, Object element) { SourceElement sourceElement = (SourceElement) element; try { IEditorDescriptor desc = IDE.getEditorDescriptor(sourceElement.getFilename()); return desc.getId(); } catch (PartInitException e) { // ignore } return sourceElement.isExternal() ? RubyUI.ID_EXTERNAL_EDITOR : RubyUI.ID_RUBY_EDITOR; } /** * @see org.eclipse.debug.ui.ISourcePresentation#getEditorInput(Object) */ public IEditorInput getEditorInput(Object element) { SourceElement sourceElement = (SourceElement) element; if (!sourceElement.isExternal()) { return new FileEditorInput(sourceElement.getWorkspaceFile()); } File filesystemFile = new File(sourceElement.getFilename()); if (filesystemFile.exists()) { return new ExternalRubyFileEditorInput(filesystemFile); } RdtDebugCorePlugin.log(IStatus.INFO, RdtDebugUiMessages.getFormattedString( RdtDebugUiMessages.RdtDebugUiPlugin_couldNotOpenFile, sourceElement.getFilename())); return null; } public class SourceElement { private String filename; private IFile workspaceFile; private RubySourceLocator sourceLocator; public SourceElement(String aFilename, RubySourceLocator pSourceLocator) { filename = aFilename; this.sourceLocator = pSourceLocator; init(); } private void init() { setFileName(); grabWorkspaceFile(); } private void setFileName() { if (filename == null) return; if (filename.startsWith("./")) { filename = filename.substring(2); } // Try relative to working dir if (sourceLocator.getAbsoluteWorkingDirectory() != null && sourceLocator.getAbsoluteWorkingDirectory().trim().length() > 0) { String relativeToWorkingDir = sourceLocator.getAbsoluteWorkingDirectory() + "/" + filename; File file = new File(relativeToWorkingDir); if (file.exists() && !file.isDirectory()) { filename = relativeToWorkingDir; return; } } // Try relative to project root if (projectName != null && projectName.trim().length() > 0) { IProject project = getProject(); String relativeToProject = project.getLocation().toOSString() + filename.substring(1); File file = new File(relativeToProject); if (file.exists() && !file.isDirectory()) { filename = relativeToProject; return; } } // Assume it's absolute... } private IProject getProject() { if (projectName == null) return null; return RdtDebugCorePlugin.getWorkspace().getRoot().getProject(projectName); } private void grabWorkspaceFile() { if (filename == null) return; // Try absolute workspaceFile = RdtDebugCorePlugin.getWorkspace().getRoot().getFileForLocation(new Path(filename)); if (workspaceFile != null && workspaceFile.exists()) return; // Try relative to workspace root try { workspaceFile = RdtDebugCorePlugin.getWorkspace().getRoot().getFile(new Path(filename)); if (workspaceFile != null && workspaceFile.exists()) return; } catch (RuntimeException e) { workspaceFile = null; } if (getProject() != null) { workspaceFile = getProject().getFile(new Path(filename)); } } public boolean isExternal() { return workspaceFile == null || !workspaceFile.exists(); } public IFile getWorkspaceFile() { return workspaceFile; } public String getFilename() { return filename; } } }