X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/launching/PHPSourceLookupParticipant.java b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/launching/PHPSourceLookupParticipant.java index d747466..5397391 100644 --- a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/launching/PHPSourceLookupParticipant.java +++ b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/launching/PHPSourceLookupParticipant.java @@ -1,17 +1,291 @@ package net.sourceforge.phpeclipse.xdebug.php.launching; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import net.sourceforge.phpeclipse.xdebug.core.PathMapItem; import net.sourceforge.phpeclipse.xdebug.php.model.XDebugStackFrame; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.model.IStackFrame; import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupParticipant; +import org.eclipse.debug.core.sourcelookup.ISourceContainer; +import org.eclipse.debug.internal.core.sourcelookup.SourceLookupMessages; public class PHPSourceLookupParticipant extends AbstractSourceLookupParticipant { + private Map pathMap = null; + private boolean remoteDebug = true; + private IPath remoteSourcePath; + private String projectName; + + /* (non-Javadoc) + * @see org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant#getSourceName(Object) + */ public String getSourceName(Object object) throws CoreException { if (object instanceof XDebugStackFrame) { - return ((XDebugStackFrame)object).getSourceName(); + return ((XDebugStackFrame) object).getFullSourceName(); } return null; } + /** + * @see org.eclipse.debug.core.model.ISourceLocator#getSourceElement(IStackFrame) + * + * Return the client side source filename for the server side source file. + * E.g. when cross debugging, the server side filename could be /var/www/index.php + * on the client side it is either a Eclipse_PHP_projectname\index.php (when it is a linked file) + * + * + * @param stackFrame The stackframe for which we want the client side source file name + * @return The filename as it appears on the client side + */ + public Object getSourceElement (IStackFrame stackFrame) throws CoreException { + IPath projectPath; + IPath remotePath; + IPath path; + IPath localPath; + Iterator iterator; + String fileName; + //String file; + String local; + List pathMap; + PathMapItem pmi = null; + + projectName = getDirector().getLaunchConfiguration().getAttribute (IXDebugConstants.ATTR_PHP_PROJECT, ""); + pathMap = getDirector().getLaunchConfiguration().getAttribute(IXDebugConstants.ATTR_PHP_PATHMAP, (List) null); + + fileName = ((XDebugStackFrame) stackFrame).getFullSourceName (); // Get the filename as it is submitted by XDebug + //file = ""; + + if (remoteDebug) { // Is it a remote debugging session + path = new Path (fileName); // Create a IPath object for the server side filename +/* + if (!remoteSourcePath.isEmpty()) { + if (remoteSourcePath.isPrefixOf (path)) { // Is the server side filename with the remote source path + path = path.removeFirstSegments (remoteSourcePath.matchingFirstSegments (path)); // Remove the remote source path + //file = path.toString (); // The filename without the remote source path + projectPath = (PHPeclipsePlugin.getWorkspace().getRoot().getProject(projectName).getLocation()); // Get the absolute project path + + return (projectPath.append (path)).toOSString (); // Return the filename as absolute client side path + } + } + else { +*/ + if (pathMap == null) { // Do we have path mapping (e.g. for cross platform debugging) + return fileName; // No, then return the filename as it given by DBG (the full server side path) + } + + pmi = null; + + for (int k = 0; k < pathMap.size(); k++) { + pmi = new PathMapItem ((String) pathMap.get(k)); + + local = pmi.getLocalPath ().toString(); // + localPath = new Path (pmi.getLocalPath().toString()); // Get the local/client side path of the mapping + remotePath = new Path (pmi.getRemotePath().toString()); // Get the remote/server side path of the mapping + + if (remotePath.isPrefixOf (path)) { // Starts the remote/server side file path with the remote/server side mapping path + path = path.removeFirstSegments (remotePath.matchingFirstSegments (path)); // Remove the absolute path from filename + + return path.toString (); +/* + localPath = new Path (local); // Create new IPath object for the local/client side path + path = localPath.append (path); // Prepend the project relative path to filename + + projectPath = (PHPeclipsePlugin.getWorkspace().getRoot().getProject(projectName).getLocation()); // Get the absolute project path + +// return path; + return (projectPath.append (path)).toString (); // Return the filename as absolute client side path +*/ + } + } +// } + + if (pathMap == null) { // Do we have path mapping (e.g. for cross platform debugging) + return fileName; // No, then return the filename as it given by DBG (the full server side path) + } + + pmi = null; + + for (int k = 0; k < pathMap.size(); k++) { + pmi = new PathMapItem((String) pathMap.get(k)); + + local = pmi.getLocalPath().toString(); // Get the local/client side path of the mapping + localPath = new Path (pmi.getLocalPath().toString()); // Get the local/client side path of the mapping + remotePath = new Path (pmi.getRemotePath().toString()); // Get the remote/server side path of the mapping + + if (remotePath.isPrefixOf (path)) { // Starts the remote/server side file path with the remote/server side mapping path + path = path.removeFirstSegments (remotePath.matchingFirstSegments (path)); // Remove the absolute path from filename + localPath = new Path (local); // Create new IPath object for the local/client side path + + return localPath.append (path).toOSString (); // Append the remote filename to the client side path (So we return the absolute path + // to the source file as the client side sees it. + } + } + + return fileName; + + } else { // no remote debug +/* + IWorkspaceRoot root = PHPLaunchingPlugin.getWorkspace().getRoot(); + Path filePath = new Path(fileName); + + if (root.getFileForLocation(filePath) == null) { + IProject proj = root.getProject(projectName); + IFile[] files = root.findFilesForLocation(filePath); + for (int i = 0; i < files.length; i++) { + if (files[i].getProject().equals(proj)) { + fileName = proj.getFullPath().append(files[i].getProjectRelativePath()).toOSString(); + break; + } + } + } +*/ + return fileName; + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant#findSourceElements(java.lang.Object) + */ + public Object[] findSourceElements(Object object) throws CoreException { + String name = null; + + if (object == null) { + return new Object[] {}; + } + XDebugStackFrame stackFrame = null; + if (object instanceof XDebugStackFrame) { + stackFrame = (XDebugStackFrame) object; + } else { + return new Object[] {}; + } + + List results = null; + CoreException single = null; + MultiStatus multiStatus = null; + + if (isFindDuplicates()) { + results = new ArrayList(); + } + + try { + name = (String) getSourceElement (stackFrame); + } + catch (CoreException e) { + } + + if (name == null || name.length() == 0) { + return new Object[] {}; + } + + // here our stackframe is guaranteed not to be null + IPath sLocalPath = null; + + if (((XDebugStackFrame) object).getThread() == null) { + IPath sPath = new Path(stackFrame.getFullName().getPath()); + List pathMap = getDirector().getLaunchConfiguration() + .getAttribute(IXDebugConstants.ATTR_PHP_PATHMAP, (List) null); + + PathMapItem pmi = null; + for (int k = 0; k < pathMap.size(); k++) { + pmi = new PathMapItem((String) pathMap.get(k)); + + IPath local = new Path(pmi.getLocalPath().toString()); + IPath remote = new Path(pmi.getRemotePath().toString()); + + if (remote.matchingFirstSegments(sPath) == remote.segmentCount()) { + sLocalPath = local; + } + } + } else { + + } + + String Type = stackFrame.getType(); + + if (Type.equals("eval")) { + results.add("pippo"); + return results.toArray(); + } + + ISourceContainer[] containers = getSourceContainers(); + for (int i = 0; i < containers.length; i++) { + ISourceContainer container = getDelegateContainer(containers[i]); + if (container == null) { + continue; + } + + try { + Object[] objects = container.findSourceElements(name); + if (objects.length > 0) { + if (isFindDuplicates()) { + if (((XDebugStackFrame) object).getThread() == null) { + addMatching(results, sLocalPath, objects); + } else { + return objects; + } + } else { + if (objects.length == 1) { + return objects; + } + return new Object[] { objects[0] }; + } + } + } catch (CoreException e) { + if (single == null) { + single = e; + } else if (multiStatus == null) { + multiStatus = new MultiStatus(DebugPlugin + .getUniqueIdentifier(), DebugPlugin.INTERNAL_ERROR, + new IStatus[] { single.getStatus() }, + SourceLookupMessages.DefaultSourceContainer_0, + null); + multiStatus.add(e.getStatus()); + } else { + multiStatus.add(e.getStatus()); + } + } + } + if (results == null) { + if (multiStatus != null) { + throw new CoreException(multiStatus); + } else if (single != null) { + throw single; + } + return EMPTY; + } + + return results.toArray(); + } + + static void addMatching(List results, IPath localPath, Object[] objects) { + if (results == null || localPath == null || objects == null) { + return; + } + for (int j = 0; j < objects.length; j++) { + if (objects[j] == null || !(objects[j] instanceof IFile)) { + continue; + } + IFile file = (IFile) objects[j]; + + IPath path = new Path(file.getLocation().toString()); + if (localPath.matchingFirstSegments(path) == localPath + .segmentCount()) { + results.add(objects[j]); + } + } + } }