1) Improvements for the XDebug plugin.
[phpeclipse.git] / net.sourceforge.phpeclipse.xdebug.core / src / net / sourceforge / phpeclipse / xdebug / php / launching / PHPSourceLookupParticipant.java
index 5e8b521..5397391 100644 (file)
 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[] {};
                }
@@ -51,7 +181,12 @@ public class PHPSourceLookupParticipant extends AbstractSourceLookupParticipant
                        results = new ArrayList();
                }
 
-               String name = getSourceName(object);
+               try {
+                   name = (String) getSourceElement (stackFrame);
+               }
+               catch (CoreException e) {
+               }
+
                if (name == null || name.length() == 0) {
                        return new Object[] {};
                }
@@ -63,20 +198,20 @@ public class PHPSourceLookupParticipant extends AbstractSourceLookupParticipant
                        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())/* .removeFirstSegments(1) */;
-                               IPath remote = new Path(pmi.getRemotePath().toString())/* .removeFirstSegments(1) */;
-       
+
+                               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();
@@ -132,6 +267,7 @@ public class PHPSourceLookupParticipant extends AbstractSourceLookupParticipant
                        }
                        return EMPTY;
                }
+
                return results.toArray();
        }
 
@@ -145,11 +281,11 @@ public class PHPSourceLookupParticipant extends AbstractSourceLookupParticipant
                        }
                        IFile file = (IFile) objects[j];
 
-                       IPath path = new Path(file.getFullPath().toString());
+                       IPath path = new Path(file.getLocation().toString());
                        if (localPath.matchingFirstSegments(path) == localPath
                                        .segmentCount()) {
                                results.add(objects[j]);
                        }
                }
        }
-}
\ No newline at end of file
+}