1) Made breakpoint working for direct script debugging (php cli) on Win systems.
[phpeclipse.git] / net.sourceforge.phpeclipse.xdebug.core / src / net / sourceforge / phpeclipse / xdebug / php / launching / PHPSourceLookupParticipant.java
index d747466..f913069 100644 (file)
 package net.sourceforge.phpeclipse.xdebug.php.launching;
 
+import java.net.URI;
+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.resources.ResourcesPlugin;
 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.ILaunchConfigurationType;
+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;
+               Object      test;
+               IProject    project;
+
+               projectName      = getDirector().getLaunchConfiguration().getAttribute (IXDebugConstants.ATTR_PHP_PROJECT, "");
+               pathMap          = getDirector().getLaunchConfiguration().getAttribute (IXDebugConstants.ATTR_PHP_PATHMAP, (List) null);        
+               project          = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
+               
+               if (getDirector ().getLaunchConfiguration ().getType ().getName ().equals ("PHP XDebug Script")) {
+                   remoteDebug = false;
+               }
+               else {
+                   remoteDebug = true;
+               }
+               
+               fileName = ((XDebugStackFrame) stackFrame).getFullSourceName ();        // Get the filename as it is submitted by XDebug
+
+           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 = (ResourcesPlugin.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 = (ResourcesPlugin.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 = ResourcesPlugin.getWorkspace().getRoot();
+               IPath 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;
+                                       }
+                               }
+                       }
+               else {
+                   projectPath = (ResourcesPlugin.getWorkspace().getRoot().getProject(projectName).getLocation());
+                   filePath    = filePath.removeFirstSegments (projectPath.matchingFirstSegments (filePath));
+                   
+                   return filePath.toString ();
+               }
+               
+                       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]);
+                       }
+               }
+       }
 }