001 package ideExtensions.customProject;
002
003 import com.bea.ide.actions.ActionSvc;
004 import com.bea.ide.debug.DebugSvc;
005 import com.bea.ide.filesystem.FileSvc;
006 import com.bea.ide.filesystem.IFile;
007 import com.bea.ide.ui.browser.BrowserSvc;
008 import com.bea.ide.util.URIUtil;
009 import com.bea.ide.util.swing.DialogUtil;
010 import com.bea.ide.workspace.IProject;
011 import com.bea.ide.workspace.IWorkspace;
012 import com.bea.ide.workspace.RunSvc;
013 import com.bea.ide.workspace.project.IRunDriver;
014 import com.bea.ide.workspace.project.IRunPreferences;
015 import java.io.File;
016 import java.net.MalformedURLException;
017 import java.net.URI;
018 import java.net.URISyntaxException;
019
020 /**
021 * A run driver for a PHP project. PHP project's don't support
022 * debugging, so this driver merely launches a browser to
023 * display either a) the currently open PHP file, or b) an
024 * index.php file is no PHP file is open. If there's no
025 * index.php file, the driver prompts the user to create one.
026 *
027 * A run driver implements IRunDriver, which provides methods
028 * that the IDE calls to find out if the project is runnable, to
029 * tell the project extension when the user is navigating into
030 * or out of the project in the Application window, and to
031 * tell the extension when the user has requested to start or
032 * stop the project. In other words, many of these methods are
033 * designed to give you an opportunity to provide enable or
034 * disable Start and Stop buttons, and to execute the project's
035 * "running" behavior.
036 *
037 * To learn more about the "run" lifecycle, set breakpoints
038 * in each of the methods and run this project. In the new
039 * instance of the IDE that is started, open or create a new
040 * PHP project, then open a PHP file in the project and click
041 * the Start button.
042 */
043 public class PhpProjectRunDriver implements IRunDriver
044 {
045 // A browser process for displaying a "running" file.
046 Process m_browserProcess = null;
047 // The project requested for running.
048 IProject m_currentProject = null;
049
050 /**
051 * Constructs an instance of this driver with the project
052 * that the user has asked to run.
053 */
054 public PhpProjectRunDriver(IProject project)
055 {
056 m_currentProject = project;
057 }
058
059 /**
060 * Called by the IDE when a project of this type is activated, such as
061 * when a project of this type is discovered to be present in
062 * the open application.
063 *
064 * This method is inherited from IProjectDriver. See PhpProjectDriver, an
065 * IProjectDriver implementation, for an example.
066 */
067 public void activate()
068 {}
069
070 /**
071 * Called by the IDE when a project of this type is deactivated, such as
072 * when a project of this type is removed from the open application.
073 *
074 * This method is inherited from IProjectDriver. See PhpProjectDriver, an
075 * IProjectDriver implementation, for an example.
076 */
077 public void deactivate()
078 {}
079
080 /**
081 * Called by the IDE when the user is opening a file in a
082 * PHP project. This method provides an opportunity to
083 * make sure the Start and Stop buttons are what they
084 * should be when the user is browsing the project.
085 */
086 public void doEnableChecks()
087 {
088 boolean isRunning = (RunSvc.get().getRunningProject() == m_currentProject);
089 if (!isRunning)
090 {
091 /**
092 * This project type doesn't support debugging, so disable that
093 * feature when the project has focus. Make sure the other
094 * buttons are enabled or disabled as appropriate.
095 */
096 RunSvc.get().setRunDebugEnabled(Boolean.TRUE);
097 RunSvc.get().setRunEnabled(Boolean.TRUE);
098 RunSvc.get().setStopEnabled(Boolean.FALSE);
099 }
100 }
101
102 /**
103 * Called by the IDE to get the debugging preferences. A PHP
104 * process doesn't really support debugging,
105 */
106 public IRunPreferences[] getPreferences()
107 {
108 IRunPreferences[] preferences = new IRunPreferences[1];
109 preferences[0] = new PhpProjectRunPreferences();
110 return preferences;
111 }
112
113 /**
114 * Called by the IDE to discover whether this project
115 * type can be run. It can.
116 */
117 public boolean isRunnable()
118 {
119 return true;
120 }
121
122 /**
123 * Called by the IDE when a PHP project has received control
124 * of the Start, Start with debug, and Stop buttons.
125 *
126 * Nothing needed here.
127 */
128 public void gainedCurrent()
129 {}
130
131 /**
132 * Called by the IDE when a PHP project has lost control
133 * of the Start, Start with debug, and Stop buttons.
134 *
135 * Nothing special needed here.
136 */
137 public void lostCurrent()
138 {}
139
140 /**
141 * Called by the IDE when the user saves properties
142 * for a PHP project. No preferences to save, so no need to handle
143 * this call.
144 */
145 public void onPreferencesSaved()
146 {}
147
148 /**
149 * Called by the IDE when the user puts the project
150 * into "run" mode while a file is open in the
151 * project (as opposed to the project merely having
152 * focus). Only PHP files can be run, so if a PHP
153 * file isn't currently open, then defer to a
154 * project-level request.
155 *
156 * @param fileUri The file that the user wants to run.
157 * @param debugRequested true if the user wants to run with
158 * debugging; otherwise false.
159 */
160 public boolean runFile(URI fileUri, boolean debugRequested)
161 {
162 boolean isRunnable = false;
163 if (fileUri.getPath().endsWith(".php"))
164 {
165 isRunnable = true;
166 enterRunState(fileUri);
167 } else
168 {
169 runProject(false);
170 }
171 return isRunnable;
172 }
173
174 /**
175 * Called by the IDE when the user puts the project
176 * into "run" mode -- such as by clicking the Start button.
177 * Note that this project type doesn't support debugging,
178 * so the <em>debugRequested</em> parameter is ignored.
179 *
180 * @param debugRequested true if the user wants to run with
181 * debugging; otherwise false.
182 */
183 public boolean runProject(boolean debugRequested)
184 {
185 IFile indexIFile = null;
186 boolean isRunnable = false;
187
188 String indexFilePath = m_currentProject.getPath() + File.separator + "index.php";
189 File indexFile = new File(indexFilePath);
190 if (indexFile.exists())
191 {
192 isRunnable = enterRunState(indexFile.toURI());
193 } else
194 {
195 showNoIndexAlert();
196 isRunnable = false;
197 }
198 return isRunnable;
199 }
200
201 /**
202 * Takes the IDE into a "running" state. For PHP projects
203 * this merely means that the Start button is disabled, the
204 * Stop button is enabled, and a browser is launched to
205 * display a PHP file.
206 */
207 private boolean enterRunState(URI fileUri)
208 {
209 boolean isRunning = false;
210 try
211 {
212 m_browserProcess = BrowserSvc.get().invokeBrowser(fileUri.toURL(), true);
213 RunSvc.get().setRunEnabled(Boolean.FALSE);
214 RunSvc.get().setRunDebugEnabled(Boolean.FALSE);
215 RunSvc.get().setStopEnabled(Boolean.TRUE);
216 // DebugSvc.get().start(m_currentProject);
217 RunSvc.get().setRunningProject(m_currentProject);
218 isRunning = true;
219 // m_currentProject.getWorkspace().setState(IWorkspace.STATE_IsRunning, _pkg.getString("runVerb"), ActionSvc.get().getAction(StopAction.class.getName()));
220 } catch (MalformedURLException mue)
221 {
222 mue.printStackTrace();
223 }
224 return isRunning;
225 }
226
227 /**
228 * Displays a dialog telling the user that they
229 * can't run the project until they've opened
230 * a PHP file, or there is an index.php file at the
231 * project's root.
232 */
233 private void showNoIndexAlert()
234 {
235 DialogUtil.showErrorDialog("This file can not be run. Please open a PHP file or " +
236 "create an index.php file at the root of the project.");
237 }
238
239 /**
240 * Called by the IDE when an application that contains a PHP
241 * project is being shut down, immediately before the
242 * shutdown occurs.
243 */
244 public void shutDown()
245 {
246 if (m_browserProcess != null)
247 {
248 m_browserProcess.destroy();
249 }
250 }
251
252 /**
253 * Called by the IDE when the running project is stopped.
254 * Running a PHP project just opens a browser, so this code
255 * just closes it.
256 */
257 public boolean stopProject()
258 {
259 RunSvc.get().setStopEnabled(Boolean.FALSE);
260 RunSvc.get().setRunEnabled(Boolean.TRUE);
261 RunSvc.get().setRunDebugEnabled(Boolean.TRUE);
262 if (m_browserProcess != null)
263 {
264 m_browserProcess.destroy();
265 }
266 return true;
267 }
268 }
|