initial implementation
[phpeclipse.git] / net.sourceforge.phpeclipse / src / test / PHPParserSuperclass.java
1 package test;
2
3 import java.text.MessageFormat;
4 import java.util.Hashtable;
5
6 import net.sourceforge.phpdt.core.IJavaModelMarker;
7 import net.sourceforge.phpdt.internal.compiler.parser.PHPOutlineInfo;
8 import net.sourceforge.phpdt.internal.core.builder.PHPBuilder;
9 import net.sourceforge.phpdt.internal.ui.util.StringUtil;
10 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
11 import net.sourceforge.phpeclipse.actions.PHPStartApacheAction;
12
13 import org.eclipse.core.resources.IFile;
14 import org.eclipse.core.resources.IMarker;
15 import org.eclipse.core.runtime.CoreException;
16 import org.eclipse.jface.preference.IPreferenceStore;
17 import org.eclipse.ui.texteditor.MarkerUtilities;
18
19 /**
20  * The superclass for our PHP parsers.
21  * @author Matthieu Casanova
22  */
23 public abstract class PHPParserSuperclass {
24   // strings for external parser call
25   private static final String PARSE_ERROR_STRING = "Parse error"; //$NON-NLS-1$
26   private static final String PARSE_WARNING_STRING = "Warning"; //$NON-NLS-1$
27   public static final int ERROR = 2;
28   public static final int WARNING = 1;
29   public static final int INFO = 0;
30   public static final int TASK = 3;
31   // TODO design error? Analyze why fileToParse must be static ???
32   protected static IFile fileToParse;
33
34   /**
35    * Call the php parse command ( php -l -f <filename> )
36    * and create markers according to the external parser output.
37    * @param file the file that will be parsed
38    */
39   public static void phpExternalParse(final IFile file) {
40     //IFile file = (IFile) resource;
41     //  final IPath path = file.getFullPath();
42     final IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore();
43     final String filename = file.getLocation().toString();
44
45     final String[] arguments = {filename};
46     final MessageFormat form = new MessageFormat(store.getString(PHPeclipsePlugin.EXTERNAL_PARSER_PREF));
47     final String command = form.format(arguments);
48
49     final String parserResult = PHPStartApacheAction.getParserOutput(command, "External parser: ");
50
51     try {
52       // parse the buffer to find the errors and warnings
53       createMarkers(parserResult, file);
54     } catch (CoreException e) {
55     }
56   }
57
58   /**
59    * Create markers according to the external parser output.
60    * @param output the external parser output
61    * @param file the file that was parsed.
62    */
63   protected static void createMarkers(final String output, final IFile file) throws CoreException {
64     // delete all markers
65 //    file.deleteMarkers(IMarker.PROBLEM, false, 0);
66                 PHPBuilder.removeProblemsAndTasksFor(file);
67
68     int indx = 0;
69     int brIndx;
70     boolean flag = true;
71     while ((brIndx = output.indexOf("<br />", indx)) != -1) {
72       // newer php error output (tested with 4.2.3)
73       scanLine(output, file, indx, brIndx);
74       indx = brIndx + 6;
75       flag = false;
76     }
77     if (flag) {
78       while ((brIndx = output.indexOf("<br>", indx)) != -1) {
79         // older php error output (tested with 4.2.3)
80         scanLine(output, file, indx, brIndx);
81         indx = brIndx + 4;
82       }
83     }
84   }
85
86   private static void scanLine(final String output, final IFile file, final int indx, final int brIndx) throws CoreException {
87     String current;
88     //  String outLineNumberString; never used
89     final StringBuffer lineNumberBuffer = new StringBuffer(10);
90     char ch;
91     current = output.substring(indx, brIndx);
92
93     if (current.indexOf(PARSE_WARNING_STRING) != -1 || current.indexOf(PARSE_ERROR_STRING) != -1) {
94       final int onLine = current.indexOf("on line <b>");
95       if (onLine != -1) {
96         lineNumberBuffer.delete(0, lineNumberBuffer.length());
97         for (int i = onLine; i < current.length(); i++) {
98           ch = current.charAt(i);
99           if ('0' <= ch && '9' >= ch) {
100             lineNumberBuffer.append(ch);
101           }
102         }
103
104         final int lineNumber = Integer.parseInt(lineNumberBuffer.toString());
105
106         final Hashtable attributes = new Hashtable();
107
108         current = StringUtil.replaceAll(current, "\n", "");
109         current = StringUtil.replaceAll(current, "<b>", "");
110         current = StringUtil.replaceAll(current, "</b>", "");
111         MarkerUtilities.setMessage(attributes, current);
112
113         if (current.indexOf(PARSE_ERROR_STRING) != -1)
114           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
115         else if (current.indexOf(PARSE_WARNING_STRING) != -1)
116           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
117         else
118           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
119         MarkerUtilities.setLineNumber(attributes, lineNumber);
120 //        MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
121                                 MarkerUtilities.createMarker(file, attributes, IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
122       }
123     }
124   }
125
126   /**
127    * This will parse the file and generate the outline info
128    * @param parent the parent object
129    * @param s the string that should be parsed
130    * @return the outline info
131    */
132   public abstract PHPOutlineInfo parseInfo(Object parent, String s);
133
134   /**
135    * This will change the file to parse.
136    * @param fileToParse the file that should be parsed
137    */
138   public abstract void setFileToParse(IFile fileToParse);
139
140   /**
141    * This will parse the given string
142    * @param s the string to parse
143    * @throws CoreException an exception that can be launched
144    */
145   public abstract void parse(String s) throws CoreException;
146
147   /**
148    * This will set a marker.
149    * @param file the file that generated the marker
150    * @param message the message
151    * @param charStart the starting character
152    * @param charEnd the end character
153    * @param errorLevel the error level ({@link PHPParserSuperclass#ERROR},
154    *        {@link PHPParserSuperclass#INFO},{@link PHPParserSuperclass#WARNING}),{@link PHPParserSuperclass#TASK})
155    * @throws CoreException an exception throwed by the MarkerUtilities
156    */
157   public static void setMarker(
158       final IFile file,
159       final String message,
160       final int charStart,
161       final int charEnd,
162       final int errorLevel)
163       throws CoreException {
164     if (file != null) {
165       final Hashtable attributes = new Hashtable();
166       MarkerUtilities.setMessage(attributes, message);
167       switch (errorLevel) {
168         case ERROR:
169           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
170           break;
171         case WARNING:
172           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
173           break;
174         case INFO:
175           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
176           break;
177         case TASK:
178           attributes.put(IMarker.SEVERITY, new Integer(IMarker.TASK));
179           break;
180       }
181       MarkerUtilities.setCharStart(attributes, charStart);
182       MarkerUtilities.setCharEnd(attributes, charEnd);
183 //      MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
184                         MarkerUtilities.createMarker(file, attributes, IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
185     }
186   }
187
188   /**
189    * This will set a marker.
190    * @param file the file that generated the marker
191    * @param message the message
192    * @param line the line number
193    * @param errorLevel the error level ({@link PHPParserSuperclass#ERROR},
194    *        {@link PHPParserSuperclass#INFO},{@link PHPParserSuperclass#WARNING})
195    * @throws CoreException an exception throwed by the MarkerUtilities
196    */
197   public static void setMarker(final IFile file,
198                                final String message,
199                                final int line,
200                                final int errorLevel,
201                                final String location)
202       throws CoreException {
203     if (file != null) {
204 //      String markerKind = IMarker.PROBLEM;
205                         String markerKind = IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER;
206       final Hashtable attributes = new Hashtable();
207       MarkerUtilities.setMessage(attributes, message);
208       switch (errorLevel) {
209         case ERROR:
210           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
211           break;
212         case WARNING:
213           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
214           break;
215         case INFO:
216           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
217           break;
218         case TASK:
219           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
220 //          markerKind = IMarker.TASK;
221           markerKind = IJavaModelMarker.TASK_MARKER;
222           break;
223       }
224       attributes.put(IMarker.LOCATION, location);
225       MarkerUtilities.setLineNumber(attributes, line);
226       MarkerUtilities.createMarker(file, attributes, markerKind);
227     }
228   }
229
230   /**
231    * This will set a marker.
232    * @param message the message
233    * @param charStart the starting character
234    * @param charEnd the end character
235    * @param errorLevel the error level ({@link PHPParserSuperclass#ERROR},
236    *        {@link PHPParserSuperclass#INFO},{@link PHPParserSuperclass#WARNING})
237    * @throws CoreException an exception throwed by the MarkerUtilities
238    */
239   public static void setMarker(final String message,
240                                final int charStart,
241                                final int charEnd,
242                                final int errorLevel,
243                                final String location)
244       throws CoreException {
245     if (fileToParse != null) {
246       setMarker(fileToParse, message, charStart, charEnd, errorLevel, location);
247     }
248   }
249
250   /**
251    * This will set a marker.
252    * @param file the file that generated the marker
253    * @param message the message
254    * @param charStart the starting character
255    * @param charEnd the end character
256    * @param errorLevel the error level ({@link PHPParserSuperclass#ERROR},
257    *        {@link PHPParserSuperclass#INFO},{@link PHPParserSuperclass#WARNING})
258    * @param location the location of the error
259    * @throws CoreException an exception throwed by the MarkerUtilities
260    */
261   public static void setMarker(final IFile file,
262                                final String message,
263                                final int charStart,
264                                final int charEnd,
265                                final int errorLevel,
266                                final String location)
267       throws CoreException {
268     if (file != null) {
269       final Hashtable attributes = new Hashtable();
270       MarkerUtilities.setMessage(attributes, message);
271       switch (errorLevel) {
272         case ERROR:
273           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
274           break;
275         case WARNING:
276           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
277           break;
278         case INFO:
279           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
280           break;
281         case TASK:
282           attributes.put(IMarker.SEVERITY, new Integer(IMarker.TASK));
283           break;
284       }
285       attributes.put(IMarker.LOCATION, location);
286       MarkerUtilities.setCharStart(attributes, charStart);
287       MarkerUtilities.setCharEnd(attributes, charEnd);
288 //      MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
289                         MarkerUtilities.createMarker(file, attributes, IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
290     }
291   }
292 }