Fix #1371992: Error with switch when last case block omits break or return
[phpeclipse.git] / net.sourceforge.phpeclipse.launching / src / net / sourceforge / phpdt / internal / launching / PHPSourceLocator.java
1 package net.sourceforge.phpdt.internal.launching;
2
3 import java.util.Iterator;
4 import java.util.Map;
5
6 import net.sourceforge.phpdt.internal.debug.core.model.PHPStackFrame;
7 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
8 import net.sourceforge.phpeclipse.builder.ExternalEditorInput;
9 import net.sourceforge.phpeclipse.builder.FileStorage;
10
11 import org.eclipse.core.resources.IFile;
12 import org.eclipse.core.runtime.CoreException;
13 import org.eclipse.core.runtime.IPath;
14 import org.eclipse.core.runtime.IStatus;
15 import org.eclipse.core.runtime.Path;
16 import org.eclipse.core.runtime.Platform;
17 import org.eclipse.debug.core.ILaunchConfiguration;
18 import org.eclipse.debug.core.model.IPersistableSourceLocator;
19 import org.eclipse.debug.core.model.IStackFrame;
20 import org.eclipse.debug.ui.ISourcePresentation;
21 import org.eclipse.ui.IEditorInput;
22 import org.eclipse.ui.IWorkbench;
23 import org.eclipse.ui.IWorkbenchPage;
24 import org.eclipse.ui.IWorkbenchWindow;
25 import org.eclipse.ui.PlatformUI;
26 import org.eclipse.ui.part.FileEditorInput;
27
28 public class PHPSourceLocator implements IPersistableSourceLocator, ISourcePresentation {
29         private String          absoluteWorkingDirectory;
30         private Map             pathMap = null;
31         private boolean         remoteDebug;
32         private IPath           remoteSourcePath;
33         private String          projectName;
34
35   public PHPSourceLocator() {
36
37   }
38
39   public String getAbsoluteWorkingDirectory() {
40     return absoluteWorkingDirectory;
41   }
42
43   /**
44    * @see org.eclipse.debug.core.model.IPersistableSourceLocator#getMemento()
45    */
46   public String getMemento() throws CoreException {
47     return null;
48   }
49
50   /**
51    * @see org.eclipse.debug.core.model.IPersistableSourceLocator#initializeFromMemento(String)
52    */
53   public void initializeFromMemento(String memento) throws CoreException {
54   }
55
56   /**
57    * @see org.eclipse.debug.core.model.IPersistableSourceLocator#initializeDefaults(ILaunchConfiguration)
58    */
59   public void initializeDefaults (ILaunchConfiguration configuration) throws CoreException {
60     this.absoluteWorkingDirectory = configuration.getAttribute (PHPLaunchConfigurationAttribute.WORKING_DIRECTORY, "");
61         this.remoteDebug              = configuration.getAttribute (PHPLaunchConfigurationAttribute.REMOTE_DEBUG,false);
62         this.pathMap                  = configuration.getAttribute (PHPLaunchConfigurationAttribute.FILE_MAP, (Map)null);
63         this.projectName              = configuration.getAttribute (PHPLaunchConfigurationAttribute.PROJECT_NAME, "");
64
65         if (Platform.getOS().equals(Platform.OS_WIN32)) {
66                 this.remoteSourcePath = new Path ((configuration.getAttribute (PHPLaunchConfigurationAttribute.REMOTE_PATH, "")).toLowerCase());
67         }
68         else {
69                 this.remoteSourcePath = new Path (configuration.getAttribute (PHPLaunchConfigurationAttribute.REMOTE_PATH, ""));
70         }
71
72 //              system.os.name
73   }
74
75   /**
76    * @see org.eclipse.debug.core.model.ISourceLocator#getSourceElement(IStackFrame)
77    *
78    * Return the client side source filename for the server side source file.
79    * E.g. when cross debugging, the server side filename could be /var/www/index.php
80    * on the client side it is either a Eclipse_PHP_projectname\index.php (when it is a linked file)
81    *
82    *
83    * @param stackFrame    The stackframe for which we want the client side source file name
84    * @return              The filename as it appears on the client side
85    */
86   public Object getSourceElement (IStackFrame stackFrame) {
87         IPath    projectPath;
88         IPath    remotePath;
89         IPath    path;
90         IPath    localPath;
91         Iterator iterator;
92         String   fileName;
93         String   file;
94         String   local;
95
96         fileName = ((PHPStackFrame) stackFrame).getFileName ();                 // Get the filename as it is submitted by DBG
97         file     = "";
98
99     if (remoteDebug) {                                              // Is it a remote debugging session
100                 path = new Path (fileName);                                 // Create a IPath object for the server side filename
101
102                 if (!remoteSourcePath.isEmpty()) {
103                         if (remoteSourcePath.isPrefixOf (path)) {                   // Is the server side filename with the remote source path
104                                 path        = path.removeFirstSegments (remoteSourcePath.matchingFirstSegments (path)); // Remove the remote source path
105                                 file        = path.toString ();                         // The filename without the remote source path
106                                 projectPath = (PHPeclipsePlugin.getWorkspace().getRoot().getProject(projectName).getLocation()); // Get the absolute project path
107
108                                 return (projectPath.append (path)).toOSString ();       // Return the filename as absolute client side path
109                         }
110                 }
111                 else {
112                         if (pathMap == null) {                                      // Do we have path mapping (e.g. for cross platform debugging)
113                                 return fileName;                                        // No, then return the filename as it given by DBG (the full server side path)
114                         }
115
116                         iterator = pathMap.keySet().iterator();
117
118                         while (iterator.hasNext ()) {
119                                 local      = (String) iterator.next ();                 // Get the local/client side path of the mapping
120                                 remotePath = new Path ((String) pathMap.get (local));   // Get the remote/server side path of the mapping
121
122                                 if (remotePath.isPrefixOf (path)) {                     // Starts the remote/server side file path with the remote/server side mapping path
123                                         path      = path.removeFirstSegments (remotePath.matchingFirstSegments (path)); // Remove the absolute path from filename
124                                         localPath = new Path (local);                       // Create new IPath object for the local/client side path
125                                         path      = localPath.append (path);                // Prepend the project relative path to filename
126
127                                         projectPath = (PHPeclipsePlugin.getWorkspace().getRoot().getProject(projectName).getLocation()); // Get the absolute project path
128
129                                         return (projectPath.append (path)).toOSString ();       // Return the filename as absolute client side path
130                                 }
131                         }
132                 }
133
134                 if (pathMap == null) {                                      // Do we have path mapping (e.g. for cross platform debugging)
135                         return fileName;                                        // No, then return the filename as it given by DBG (the full server side path)
136                 }
137
138                 iterator = pathMap.keySet().iterator();
139
140                 while (iterator.hasNext ()) {
141                         local      = (String) iterator.next ();                 // Get the local/client side path of the mapping
142                         remotePath = new Path ((String) pathMap.get (local));   // Get the remote/server side path of the mapping
143
144                         if (remotePath.isPrefixOf (path)) {                     // Starts the remote/server side file path with the remote/server side mapping path
145                                 path      = path.removeFirstSegments (remotePath.matchingFirstSegments (path)); // Remove the absolute path from filename
146                                 localPath = new Path (local);                       // Create new IPath object for the local/client side path
147
148                                 return localPath.append (path).toOSString ();       // Append the remote filename to the client side path (So we return the absolute path
149                                                                                                                                         // to the source file as the client side sees it.
150                         }
151                 }
152
153                 return fileName;
154         } else {
155                 return fileName;
156     }
157   }
158
159   /**
160    * @see org.eclipse.debug.ui.ISourcePresentation#getEditorId(IEditorInput, Object)
161    */
162   public String getEditorId(IEditorInput input, Object element) {
163     return PlatformUI.getWorkbench().getEditorRegistry().getDefaultEditor((String) element).getId();
164   }
165
166   /**
167    * @see org.eclipse.debug.ui.ISourcePresentation#getEditorInput(Object)
168    *
169    * @param element The absolute local/client side file path
170    */
171   public IEditorInput getEditorInput (Object element) {
172         String           filename;
173         IWorkbench       workbench;
174         IWorkbenchWindow window;
175     IWorkbenchPage   page;
176         IPath            path;
177         IFile            eclipseFile;
178
179     filename  = (String) element;
180     workbench = PlatformUI.getWorkbench ();
181     window    = workbench.getWorkbenchWindows ()[0];
182     page      = window.getActivePage ();
183     path      = new Path (filename);                                // Create an IPath object of the absolute local/client side file name
184
185     // If the file exists in the workspace, open it
186     eclipseFile = PHPeclipsePlugin.getWorkspace().getRoot().getFileForLocation (path);
187
188     //    IFile eclipseFile = PHPeclipsePlugin.getWorkspace().getRoot().getFileForLocation(new Path(filename));
189 //    if (eclipseFile == null) {
190 //      filename = this.getAbsoluteWorkingDirectory() + "/" + filename;
191 //      eclipseFile = PHPeclipsePlugin.getWorkspace().getRoot().getFileForLocation(new Path(filename));
192 //      if (eclipseFile == null) {
193 //        PHPeclipsePlugin.log(IStatus.INFO, "Could not find file \"" + element + "\".");
194 //        return null;
195 //      }
196 //    } else
197
198     if (eclipseFile == null || !eclipseFile.exists ()) {
199       //                Otherwise open the stream directly
200           //
201       if (page == null) {
202         PHPeclipsePlugin.log(IStatus.INFO, "Could not find file \"" + element + "\".");
203         return null;
204       }
205
206       FileStorage storage = new FileStorage (path);
207       storage.setReadOnly ();
208
209       //      IEditorRegistry registry = workbench.getEditorRegistry();
210       //      IEditorDescriptor desc = registry.getDefaultEditor(filename);
211       //      if (desc == null) {
212       //        desc = registry.getDefaultEditor();
213       //      }
214       return new ExternalEditorInput(storage);
215     }
216
217     return new FileEditorInput (eclipseFile);
218   }
219 }