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).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]); } } } }