1 package net.sourceforge.phpeclipse.xdebug.php.launching;
 
   3 import java.util.ArrayList;
 
   4 import java.util.Iterator;
 
   8 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
 
   9 import net.sourceforge.phpeclipse.xdebug.core.PathMapItem;
 
  10 import net.sourceforge.phpeclipse.xdebug.php.model.XDebugStackFrame;
 
  12 import org.eclipse.core.resources.IFile;
 
  13 import org.eclipse.core.resources.IProject;
 
  14 import org.eclipse.core.resources.IWorkspaceRoot;
 
  15 import org.eclipse.core.runtime.CoreException;
 
  16 import org.eclipse.core.runtime.IPath;
 
  17 import org.eclipse.core.runtime.IStatus;
 
  18 import org.eclipse.core.runtime.MultiStatus;
 
  19 import org.eclipse.core.runtime.Path;
 
  20 import org.eclipse.debug.core.DebugPlugin;
 
  21 import org.eclipse.debug.core.model.IStackFrame;
 
  22 import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupParticipant;
 
  23 import org.eclipse.debug.core.sourcelookup.ISourceContainer;
 
  24 import org.eclipse.debug.internal.core.sourcelookup.SourceLookupMessages;
 
  26 public class PHPSourceLookupParticipant extends AbstractSourceLookupParticipant {
 
  28         private Map             pathMap         = null;
 
  29         private boolean         remoteDebug = true;
 
  30         private IPath           remoteSourcePath;
 
  31         private String          projectName;
 
  34          * @see org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant#getSourceName(Object)
 
  36         public String getSourceName(Object object) throws CoreException {
 
  37                 if (object instanceof XDebugStackFrame) {
 
  38                         return ((XDebugStackFrame) object).getFullSourceName();
 
  44            * @see org.eclipse.debug.core.model.ISourceLocator#getSourceElement(IStackFrame)
 
  46            * Return the client side source filename for the server side source file.
 
  47            * E.g. when cross debugging, the server side filename could be /var/www/index.php
 
  48            * on the client side it is either a Eclipse_PHP_projectname\index.php (when it is a linked file)
 
  51            * @param stackFrame    The stackframe for which we want the client side source file name
 
  52            * @return              The filename as it appears on the client side
 
  54           public Object getSourceElement (IStackFrame stackFrame) throws CoreException {
 
  64                 PathMapItem pmi = null;
 
  66                 projectName      = getDirector().getLaunchConfiguration().getAttribute (IXDebugConstants.ATTR_PHP_PROJECT, "");
 
  67                 pathMap          = getDirector().getLaunchConfiguration().getAttribute(IXDebugConstants.ATTR_PHP_PATHMAP, (List) null);
 
  69                 fileName = ((XDebugStackFrame) stackFrame).getFullSourceName ();        // Get the filename as it is submitted by XDebug
 
  72             if (remoteDebug) {                                                  // Is it a remote debugging session
 
  73                         path = new Path (fileName);                                     // Create a IPath object for the server side filename
 
  75                         if (!remoteSourcePath.isEmpty()) {
 
  76                                 if (remoteSourcePath.isPrefixOf (path)) {                   // Is the server side filename with the remote source path
 
  77                                         path        = path.removeFirstSegments (remoteSourcePath.matchingFirstSegments (path)); // Remove the remote source path
 
  78                                         //file        = path.toString ();                         // The filename without the remote source path
 
  79                                         projectPath = (PHPeclipsePlugin.getWorkspace().getRoot().getProject(projectName).getLocation()); // Get the absolute project path
 
  81                                         return (projectPath.append (path)).toOSString ();       // Return the filename as absolute client side path
 
  86                                 if (pathMap == null) {                                      // Do we have path mapping (e.g. for cross platform debugging)
 
  87                                         return fileName;                                        // No, then return the filename as it given by DBG (the full server side path)
 
  92                                 for (int k = 0; k < pathMap.size(); k++) {
 
  93                                         pmi = new PathMapItem ((String) pathMap.get(k));
 
  95                                         local      = pmi.getLocalPath ().toString();            //
 
  96                                         localPath  = new Path (pmi.getLocalPath().toString());  // Get the local/client side path of the mapping
 
  97                                         remotePath = new Path (pmi.getRemotePath().toString()); // Get the remote/server side path of the mapping
 
  99                                         if (remotePath.isPrefixOf (path)) {                     // Starts the remote/server side file path with the remote/server side mapping path
 
 100                                                 path      = path.removeFirstSegments (remotePath.matchingFirstSegments (path)); // Remove the absolute path from filename
 
 102                                                 return path.toString ();
 
 104                                                 localPath = new Path (local);                       // Create new IPath object for the local/client side path
 
 105                                                 path      = localPath.append (path);                // Prepend the project relative path to filename
 
 107                                                 projectPath = (PHPeclipsePlugin.getWorkspace().getRoot().getProject(projectName).getLocation()); // Get the absolute project path
 
 110                                                 return (projectPath.append (path)).toString ();   // Return the filename as absolute client side path
 
 116                         if (pathMap == null) {                                      // Do we have path mapping (e.g. for cross platform debugging)
 
 117                                 return fileName;                                        // No, then return the filename as it given by DBG (the full server side path)
 
 122                         for (int k = 0; k < pathMap.size(); k++) {
 
 123                                 pmi = new PathMapItem((String) pathMap.get(k));
 
 125                                 local      = pmi.getLocalPath().toString();             // Get the local/client side path of the mapping
 
 126                                 localPath  = new Path (pmi.getLocalPath().toString());  // Get the local/client side path of the mapping
 
 127                                 remotePath = new Path (pmi.getRemotePath().toString()); // Get the remote/server side path of the mapping
 
 129                                 if (remotePath.isPrefixOf (path)) {                     // Starts the remote/server side file path with the remote/server side mapping path
 
 130                                         path      = path.removeFirstSegments (remotePath.matchingFirstSegments (path)); // Remove the absolute path from filename
 
 131                                         localPath = new Path (local);                       // Create new IPath object for the local/client side path
 
 133                                         return localPath.append (path).toOSString ();       // Append the remote filename to the client side path (So we return the absolute path
 
 134                                                                                                                                                 // to the source file as the client side sees it.
 
 140             } else { // no remote debug
 
 142                 IWorkspaceRoot root = PHPLaunchingPlugin.getWorkspace().getRoot();
 
 143                 Path filePath = new Path(fileName);
 
 145                 if (root.getFileForLocation(filePath) == null) {
 
 146                                 IProject proj = root.getProject(projectName);
 
 147                                 IFile[] files = root.findFilesForLocation(filePath);
 
 148                                 for (int i = 0; i < files.length; i++) {
 
 149                                         if (files[i].getProject().equals(proj)) {
 
 150                                                 fileName = proj.getFullPath().append(files[i].getProjectRelativePath()).toOSString();
 
 161          * @see org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant#findSourceElements(java.lang.Object)
 
 163         public Object[] findSourceElements(Object object) throws CoreException {
 
 166                 if (object == null) {
 
 167                         return new Object[] {};
 
 169                 XDebugStackFrame stackFrame = null;
 
 170                 if (object instanceof XDebugStackFrame) {
 
 171                         stackFrame = (XDebugStackFrame) object;
 
 173                         return new Object[] {};
 
 177                 CoreException single = null;
 
 178                 MultiStatus multiStatus = null;
 
 180                 if (isFindDuplicates()) {
 
 181                         results = new ArrayList();
 
 185                     name = (String) getSourceElement (stackFrame);
 
 187                 catch (CoreException e) {
 
 190                 if (name == null || name.length() == 0) {
 
 191                         return new Object[] {};
 
 194                 // here our stackframe is guaranteed not to be null
 
 195                 IPath sLocalPath = null;
 
 197                 if (((XDebugStackFrame) object).getThread() == null) {
 
 198                         IPath sPath = new Path(stackFrame.getFullName().getPath());
 
 199                         List pathMap = getDirector().getLaunchConfiguration()
 
 200                                         .getAttribute(IXDebugConstants.ATTR_PHP_PATHMAP, (List) null);
 
 202                         PathMapItem pmi = null;
 
 203                         for (int k = 0; k < pathMap.size(); k++) {
 
 204                                 pmi = new PathMapItem((String) pathMap.get(k));
 
 206                                 IPath local = new Path(pmi.getLocalPath().toString());
 
 207                                 IPath remote = new Path(pmi.getRemotePath().toString());
 
 209                                 if (remote.matchingFirstSegments(sPath) == remote.segmentCount()) {
 
 217                 String Type = stackFrame.getType();
 
 219                 if (Type.equals("eval")) {
 
 220                         results.add("pippo");
 
 221                         return results.toArray();
 
 224                 ISourceContainer[] containers = getSourceContainers();
 
 225                 for (int i = 0; i < containers.length; i++) {
 
 226                         ISourceContainer container = getDelegateContainer(containers[i]);
 
 227                         if (container == null) {
 
 232                                 Object[] objects = container.findSourceElements(name);
 
 233                                 if (objects.length > 0) {
 
 234                                         if (isFindDuplicates()) {
 
 235                                                 if (((XDebugStackFrame) object).getThread() == null) {
 
 236                                                         addMatching(results, sLocalPath, objects);
 
 241                                                 if (objects.length == 1) {
 
 244                                                 return new Object[] { objects[0] };
 
 247                         } catch (CoreException e) {
 
 248                                 if (single == null) {
 
 250                                 } else if (multiStatus == null) {
 
 251                                         multiStatus = new MultiStatus(DebugPlugin
 
 252                                                         .getUniqueIdentifier(), DebugPlugin.INTERNAL_ERROR,
 
 253                                                         new IStatus[] { single.getStatus() },
 
 254                                                         SourceLookupMessages.DefaultSourceContainer_0,
 
 256                                         multiStatus.add(e.getStatus());
 
 258                                         multiStatus.add(e.getStatus());
 
 262                 if (results == null) {
 
 263                         if (multiStatus != null) {
 
 264                                 throw new CoreException(multiStatus);
 
 265                         } else if (single != null) {
 
 271                 return results.toArray();
 
 274         static void addMatching(List results, IPath localPath, Object[] objects) {
 
 275                 if (results == null || localPath == null || objects == null) {
 
 278                 for (int j = 0; j < objects.length; j++) {
 
 279                         if (objects[j] == null || !(objects[j] instanceof IFile)) {
 
 282                         IFile file = (IFile) objects[j];
 
 284                         IPath path = new Path(file.getLocation().toString());
 
 285                         if (localPath.matchingFirstSegments(path) == localPath
 
 287                                 results.add(objects[j]);