1 package net.sourceforge.phpdt.externaltools.actions;
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.text.MessageFormat;
6 import java.util.Hashtable;
8 import net.sourceforge.phpdt.externaltools.util.StringUtil;
9 import net.sourceforge.phpeclipse.externaltools.ExternalToolsPlugin;
10 import net.sourceforge.phpeclipse.externaltools.PHPConsole;
12 import org.eclipse.core.resources.IFile;
13 import org.eclipse.core.resources.IMarker;
14 import org.eclipse.core.runtime.CoreException;
15 import org.eclipse.jface.dialogs.MessageDialog;
16 import org.eclipse.jface.preference.IPreferenceStore;
17 import org.eclipse.ui.texteditor.MarkerUtilities;
20 * Calls the external parser and generates problem markers if necessary
22 public class ExternalPHPParser {
23 private final static String PROBLEM_ID = "net.sourceforge.phpeclipse.problem";
25 // strings for external parser call
26 private static final String PARSE_ERROR_STRING = "Parse error"; //$NON-NLS-1$
28 private static final String PARSE_WARNING_STRING = "Warning"; //$NON-NLS-1$
30 public static final int ERROR = 2;
32 public static final int WARNING = 1;
34 public static final int INFO = 0;
36 public static final int TASK = 3;
38 // TODO design error? Analyze why fileToParse must be static ???
39 final protected IFile fFileToParse;
41 public ExternalPHPParser(IFile file) {
46 * Call the php parse command ( php -l -f <filename> ) and create
47 * markers according to the external parser output.
50 * the file that will be parsed
52 public void phpExternalParse() {
53 // IFile file = (IFile) resource;
54 // final IPath path = file.getFullPath();
55 final IPreferenceStore store = ExternalToolsPlugin.getDefault()
56 .getPreferenceStore();
57 final String filename = fFileToParse.getFullPath().toString();
59 final String[] arguments = { filename };
60 final MessageFormat form = new MessageFormat(store
61 .getString(ExternalToolsPlugin.EXTERNAL_PARSER_PREF));
62 final String command = form.format(arguments);
64 final String parserResult = getParserOutput(command,
68 // parse the buffer to find the errors and warnings
69 createMarkers(parserResult, fFileToParse);
70 } catch (CoreException e) {
75 * Create markers according to the external parser output.
78 * the external parser output
80 * the file that was parsed.
82 protected void createMarkers(final String output, final IFile file)
83 throws CoreException {
85 file.deleteMarkers(PROBLEM_ID, false, 0);
90 while ((brIndx = output.indexOf("<br />", indx)) != -1) {
91 // newer php error output (tested with 4.2.3)
92 scanLine(output, file, indx, brIndx);
97 while ((brIndx = output.indexOf("<br>", indx)) != -1) {
98 // older php error output (tested with 4.2.3)
99 scanLine(output, file, indx, brIndx);
105 private void scanLine(final String output, final IFile file,
106 final int indx, final int brIndx) throws CoreException {
108 // String outLineNumberString; never used
109 final StringBuffer lineNumberBuffer = new StringBuffer(10);
111 current = output.substring(indx, brIndx);
113 if (current.indexOf(PARSE_WARNING_STRING) != -1
114 || current.indexOf(PARSE_ERROR_STRING) != -1) {
115 final int onLine = current.indexOf("on line <b>");
117 lineNumberBuffer.delete(0, lineNumberBuffer.length());
118 for (int i = onLine; i < current.length(); i++) {
119 ch = current.charAt(i);
120 if ('0' <= ch && '9' >= ch) {
121 lineNumberBuffer.append(ch);
125 final int lineNumber = Integer.parseInt(lineNumberBuffer
128 final Hashtable attributes = new Hashtable();
130 current = StringUtil.replaceAll(current, "\n", "");
131 current = StringUtil.replaceAll(current, "<b>", "");
132 current = StringUtil.replaceAll(current, "</b>", "");
133 MarkerUtilities.setMessage(attributes, current);
135 if (current.indexOf(PARSE_ERROR_STRING) != -1)
136 attributes.put(IMarker.SEVERITY, new Integer(
137 IMarker.SEVERITY_ERROR));
138 else if (current.indexOf(PARSE_WARNING_STRING) != -1)
139 attributes.put(IMarker.SEVERITY, new Integer(
140 IMarker.SEVERITY_WARNING));
142 attributes.put(IMarker.SEVERITY, new Integer(
143 IMarker.SEVERITY_INFO));
144 MarkerUtilities.setLineNumber(attributes, lineNumber);
145 MarkerUtilities.createMarker(file, attributes, PROBLEM_ID);
151 * This will set a marker.
154 * the file that generated the marker
158 * the starting character
162 * the error level ({@link ExternalPHPParser#ERROR},{@link ExternalPHPParser#INFO},{@link ExternalPHPParser#WARNING}),
163 * {@link ExternalPHPParser#TASK})
164 * @throws CoreException
165 * an exception throwed by the MarkerUtilities
167 private void setMarker(final IFile file, final String message,
168 final int charStart, final int charEnd, final int errorLevel)
169 throws CoreException {
171 final Hashtable attributes = new Hashtable();
172 MarkerUtilities.setMessage(attributes, message);
173 switch (errorLevel) {
175 attributes.put(IMarker.SEVERITY, new Integer(
176 IMarker.SEVERITY_ERROR));
179 attributes.put(IMarker.SEVERITY, new Integer(
180 IMarker.SEVERITY_WARNING));
183 attributes.put(IMarker.SEVERITY, new Integer(
184 IMarker.SEVERITY_INFO));
187 attributes.put(IMarker.SEVERITY, new Integer(IMarker.TASK));
190 MarkerUtilities.setCharStart(attributes, charStart);
191 MarkerUtilities.setCharEnd(attributes, charEnd);
192 MarkerUtilities.createMarker(file, attributes, PROBLEM_ID);
197 * This will set a marker.
200 * the file that generated the marker
206 * the error level ({@link ExternalPHPParser#ERROR},{@link ExternalPHPParser#INFO},{@link ExternalPHPParser#WARNING})
207 * @throws CoreException
208 * an exception throwed by the MarkerUtilities
210 private void setMarker(final IFile file, final String message,
211 final int line, final int errorLevel, final String location)
212 throws CoreException {
214 String markerKind = PROBLEM_ID;
215 final Hashtable attributes = new Hashtable();
216 MarkerUtilities.setMessage(attributes, message);
217 switch (errorLevel) {
219 attributes.put(IMarker.SEVERITY, new Integer(
220 IMarker.SEVERITY_ERROR));
223 attributes.put(IMarker.SEVERITY, new Integer(
224 IMarker.SEVERITY_WARNING));
227 attributes.put(IMarker.SEVERITY, new Integer(
228 IMarker.SEVERITY_INFO));
231 attributes.put(IMarker.SEVERITY, new Integer(
232 IMarker.SEVERITY_INFO));
233 markerKind = IMarker.TASK;
236 attributes.put(IMarker.LOCATION, location);
237 MarkerUtilities.setLineNumber(attributes, line);
238 MarkerUtilities.createMarker(file, attributes, markerKind);
243 * This will set a marker.
248 * the starting character
252 * the error level ({@link ExternalPHPParser#ERROR},{@link ExternalPHPParser#INFO},{@link ExternalPHPParser#WARNING})
253 * @throws CoreException
254 * an exception throwed by the MarkerUtilities
256 private void setMarker(final String message, final int charStart,
257 final int charEnd, final int errorLevel, final String location)
258 throws CoreException {
259 if (fFileToParse != null) {
260 setMarker(fFileToParse, message, charStart, charEnd, errorLevel,
266 * This will set a marker.
269 * the file that generated the marker
273 * the starting character
277 * the error level ({@link ExternalPHPParser#ERROR},{@link ExternalPHPParser#INFO},{@link ExternalPHPParser#WARNING})
279 * the location of the error
280 * @throws CoreException
281 * an exception throwed by the MarkerUtilities
283 private void setMarker(final IFile file, final String message,
284 final int charStart, final int charEnd, final int errorLevel,
285 final String location) throws CoreException {
287 final Hashtable attributes = new Hashtable();
288 MarkerUtilities.setMessage(attributes, message);
289 switch (errorLevel) {
291 attributes.put(IMarker.SEVERITY, new Integer(
292 IMarker.SEVERITY_ERROR));
295 attributes.put(IMarker.SEVERITY, new Integer(
296 IMarker.SEVERITY_WARNING));
299 attributes.put(IMarker.SEVERITY, new Integer(
300 IMarker.SEVERITY_INFO));
303 attributes.put(IMarker.SEVERITY, new Integer(IMarker.TASK));
306 attributes.put(IMarker.LOCATION, location);
307 MarkerUtilities.setCharStart(attributes, charStart);
308 MarkerUtilities.setCharEnd(attributes, charEnd);
309 MarkerUtilities.createMarker(file, attributes, PROBLEM_ID); // IMarker.PROBLEM);
313 private String getParserOutput(String command, String consoleMessage) {
315 PHPConsole console = new PHPConsole();
317 console.println(consoleMessage + command);
318 } catch (Throwable th) {
322 Runtime runtime = Runtime.getRuntime();
325 Process p = runtime.exec(command);
327 // gets the input stream to have the post-compile-time information
328 InputStream stream = p.getInputStream();
330 // get the string from Stream
331 String consoleOutput = PHPConsole.getStringFromStream(stream);
333 // prints out the information
334 if (console != null) {
335 console.print(consoleOutput);
337 return consoleOutput;
339 } catch (IOException e) {
341 .openInformation(null, "IOException: ", e.getMessage());