5397391ad0ffabf3f5d79d874be38067fe87d32d
[phpeclipse.git] / net.sourceforge.phpeclipse.xdebug.core / src / net / sourceforge / phpeclipse / xdebug / php / launching / PHPSourceLookupParticipant.java
1 package net.sourceforge.phpeclipse.xdebug.php.launching;
2
3 import java.util.ArrayList;
4 import java.util.Iterator;
5 import java.util.List;
6 import java.util.Map;
7
8 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
9 import net.sourceforge.phpeclipse.xdebug.core.PathMapItem;
10 import net.sourceforge.phpeclipse.xdebug.php.model.XDebugStackFrame;
11
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;
25
26 public class PHPSourceLookupParticipant extends AbstractSourceLookupParticipant {
27
28         private Map             pathMap         = null;
29         private boolean         remoteDebug = true;
30         private IPath           remoteSourcePath;
31         private String          projectName;
32
33         /* (non-Javadoc)
34          * @see org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant#getSourceName(Object)
35          */
36         public String getSourceName(Object object) throws CoreException {
37                 if (object instanceof XDebugStackFrame) {
38                         return ((XDebugStackFrame) object).getFullSourceName();
39                 }
40                 return null;
41         }
42
43           /**
44            * @see org.eclipse.debug.core.model.ISourceLocator#getSourceElement(IStackFrame)
45            *
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)
49            *
50            *
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
53            */
54           public Object getSourceElement (IStackFrame stackFrame) throws CoreException {
55                 IPath           projectPath;
56                 IPath           remotePath;
57                 IPath           path;
58                 IPath           localPath;
59                 Iterator        iterator;
60                 String          fileName;
61                 //String   file;
62                 String          local;
63                 List            pathMap;
64                 PathMapItem pmi = null;
65
66                 projectName      = getDirector().getLaunchConfiguration().getAttribute (IXDebugConstants.ATTR_PHP_PROJECT, "");
67                 pathMap          = getDirector().getLaunchConfiguration().getAttribute(IXDebugConstants.ATTR_PHP_PATHMAP, (List) null);
68
69                 fileName = ((XDebugStackFrame) stackFrame).getFullSourceName ();        // Get the filename as it is submitted by XDebug
70                 //file     = "";
71
72             if (remoteDebug) {                                                  // Is it a remote debugging session
73                         path = new Path (fileName);                                     // Create a IPath object for the server side filename
74 /*
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
80
81                                         return (projectPath.append (path)).toOSString ();       // Return the filename as absolute client side path
82                                 }
83                         }
84                         else {
85 */
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)
88                                 }
89
90                                 pmi = null;
91
92                                 for (int k = 0; k < pathMap.size(); k++) {
93                                         pmi = new PathMapItem ((String) pathMap.get(k));
94
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
98
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
101
102                                                 return path.toString ();
103 /*
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
106
107                                                 projectPath = (PHPeclipsePlugin.getWorkspace().getRoot().getProject(projectName).getLocation()); // Get the absolute project path
108
109 //                                              return path;
110                                                 return (projectPath.append (path)).toString ();   // Return the filename as absolute client side path
111 */
112                                         }
113                                 }
114 //                      }
115
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)
118                         }
119
120                         pmi = null;
121
122                         for (int k = 0; k < pathMap.size(); k++) {
123                                 pmi = new PathMapItem((String) pathMap.get(k));
124
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
128
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
132
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.
135                                 }
136                         }
137
138                         return fileName;
139
140             } else { // no remote debug
141 /*
142                 IWorkspaceRoot root = PHPLaunchingPlugin.getWorkspace().getRoot();
143                 Path filePath = new Path(fileName);
144
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();
151                                                 break;
152                                         }
153                                 }
154                         }
155 */
156                         return fileName;
157             }
158           }
159
160         /* (non-Javadoc)
161          * @see org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant#findSourceElements(java.lang.Object)
162          */
163         public Object[] findSourceElements(Object object) throws CoreException {
164                 String name = null;
165
166                 if (object == null) {
167                         return new Object[] {};
168                 }
169                 XDebugStackFrame stackFrame = null;
170                 if (object instanceof XDebugStackFrame) {
171                         stackFrame = (XDebugStackFrame) object;
172                 } else {
173                         return new Object[] {};
174                 }
175
176                 List results = null;
177                 CoreException single = null;
178                 MultiStatus multiStatus = null;
179
180                 if (isFindDuplicates()) {
181                         results = new ArrayList();
182                 }
183
184                 try {
185                     name = (String) getSourceElement (stackFrame);
186                 }
187                 catch (CoreException e) {
188                 }
189
190                 if (name == null || name.length() == 0) {
191                         return new Object[] {};
192                 }
193
194                 // here our stackframe is guaranteed not to be null
195                 IPath sLocalPath = null;
196
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);
201
202                         PathMapItem pmi = null;
203                         for (int k = 0; k < pathMap.size(); k++) {
204                                 pmi = new PathMapItem((String) pathMap.get(k));
205
206                                 IPath local = new Path(pmi.getLocalPath().toString());
207                                 IPath remote = new Path(pmi.getRemotePath().toString());
208
209                                 if (remote.matchingFirstSegments(sPath) == remote.segmentCount()) {
210                                         sLocalPath = local;
211                                 }
212                         }
213                 } else {
214
215                 }
216
217                 String Type = stackFrame.getType();
218
219                 if (Type.equals("eval")) {
220                         results.add("pippo");
221                         return results.toArray();
222                 }
223
224                 ISourceContainer[] containers = getSourceContainers();
225                 for (int i = 0; i < containers.length; i++) {
226                         ISourceContainer container = getDelegateContainer(containers[i]);
227                         if (container == null) {
228                                 continue;
229                         }
230
231                         try {
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);
237                                                 } else {
238                                                         return objects;
239                                                 }
240                                         } else {
241                                                 if (objects.length == 1) {
242                                                         return objects;
243                                                 }
244                                                 return new Object[] { objects[0] };
245                                         }
246                                 }
247                         } catch (CoreException e) {
248                                 if (single == null) {
249                                         single = e;
250                                 } else if (multiStatus == null) {
251                                         multiStatus = new MultiStatus(DebugPlugin
252                                                         .getUniqueIdentifier(), DebugPlugin.INTERNAL_ERROR,
253                                                         new IStatus[] { single.getStatus() },
254                                                         SourceLookupMessages.DefaultSourceContainer_0,
255                                                         null);
256                                         multiStatus.add(e.getStatus());
257                                 } else {
258                                         multiStatus.add(e.getStatus());
259                                 }
260                         }
261                 }
262                 if (results == null) {
263                         if (multiStatus != null) {
264                                 throw new CoreException(multiStatus);
265                         } else if (single != null) {
266                                 throw single;
267                         }
268                         return EMPTY;
269                 }
270
271                 return results.toArray();
272         }
273
274         static void addMatching(List results, IPath localPath, Object[] objects) {
275                 if (results == null || localPath == null || objects == null) {
276                         return;
277                 }
278                 for (int j = 0; j < objects.length; j++) {
279                         if (objects[j] == null || !(objects[j] instanceof IFile)) {
280                                 continue;
281                         }
282                         IFile file = (IFile) objects[j];
283
284                         IPath path = new Path(file.getLocation().toString());
285                         if (localPath.matchingFirstSegments(path) == localPath
286                                         .segmentCount()) {
287                                 results.add(objects[j]);
288                         }
289                 }
290         }
291 }