Added PHPUnitEditor and corresponding PHPPreferencePage
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / phpeditor / PHPSyntaxParserThread.java
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPSyntaxParserThread.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPSyntaxParserThread.java
new file mode 100644 (file)
index 0000000..79130b0
--- /dev/null
@@ -0,0 +1,421 @@
+package net.sourceforge.phpeclipse.phpeditor;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.editors.text.TextEditor;
+
+import test.PHPParserManager;
+import test.PHPParserSuperclass;
+
+
+public class PHPSyntaxParserThread extends Thread {
+  private static String[] EXTENSIONS = { ".php", ".php3", ".php4", ".inc", ".phtml" };
+
+       private String text = "";
+       private String previousText = "";
+
+       private boolean stopValidation = false;
+       private boolean validationTerminated = false;
+       private boolean isActive = false;
+
+       private TextEditor fTextEditor;
+       private ISourceViewer fSourceViewer;
+
+       private int previousHashCode = 0;
+       // Defaults
+       private int validationInterval = 2000; //millis
+       private int waitForTermination = 400; // millis
+       private int maxErrorsShown = 10;
+
+       public PHPSyntaxParserThread(
+               TextEditor textEditor,
+               ISourceViewer viewer) {
+               super();
+               fTextEditor = textEditor;
+               fSourceViewer = viewer;
+       }
+
+       public void setText(String text) {
+               if (!isActive)
+                       this.text = text;
+       }
+
+       public void setText(String text, boolean forceUpdate) {
+               if (!isActive) {
+                       this.text = text;
+               }
+
+               if (forceUpdate) {
+                       this.previousText = "";
+                       this.previousHashCode = 0;
+               }
+       }
+
+       public String getText() {
+               return text;
+       }
+
+       public void setInterval(int millis) {
+               this.validationInterval = millis;
+       }
+
+       public int getInterval() {
+               return validationInterval;
+       }
+
+       public void setErrorsShown(int number) {
+               this.maxErrorsShown = number;
+       }
+
+       public int getErrorsShown() {
+               return maxErrorsShown;
+       }
+
+       public void dispose() {
+               this.stopValidation = true;
+
+               if (validationTerminated == false) {
+
+                       try {
+                               Thread.sleep(waitForTermination);
+                       } catch (Exception e) {
+                       }
+               }
+       }
+
+       public void run() {
+               while (stopValidation == false) {
+                       try {
+
+                               this.isActive = true;
+                               boolean ret = this.validateSyntax();
+
+                               this.previousText = this.text;
+                               this.isActive = false;
+
+                               Thread.sleep(validationInterval);
+
+                       } catch (Exception e) {
+                               e.printStackTrace();
+                       }
+               }
+
+               this.validationTerminated = true;
+       }
+
+       public boolean validateSyntax() {
+
+    boolean phpFlag = false;
+    try {
+      IFile fileToParse = getPHPFile(fTextEditor.getEditorInput());
+      if (fileToParse == null) {
+        // should never happen
+        System.err.println("Error : no file in the editor");
+        // should throw an exception
+        return false;
+      }
+      String name = fileToParse.getName();
+      for (int i = 0; i<EXTENSIONS.length; i++) {
+        if (name.endsWith(EXTENSIONS[i])) {
+          phpFlag = true;  // php file extension
+          break;
+        }
+      }
+      if (phpFlag) {
+        IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore();
+        if (store.getString(PHPeclipsePlugin.PHP_PARSER_DEFAULT).equals(PHPeclipsePlugin.PHP_INTERNAL_PARSER)) {
+          // first delete all the previous markers
+          fileToParse.deleteMarkers(IMarker.PROBLEM, false, 0);
+
+          try {
+            InputStream iStream = fileToParse.getContents();
+            //        int c = iStream.read();
+            parse(fileToParse, iStream);
+            iStream.close();
+          } catch (IOException e) {
+          }
+        } else {
+          PHPParserSuperclass.phpExternalParse(fileToParse);
+        }
+      }
+    } catch (CoreException e) {
+    }
+
+//
+//             Process proc = null;
+//
+//             if (this.previousText.equals(this.text)) {
+//                     return true;
+//             }
+//
+//             try {
+//                     IEditorInput input = fTextEditor.getEditorInput();
+//                     IResource resource =
+//                             (IResource) ((IAdaptable) input).getAdapter(IResource.class);
+//
+//                     // Write output file
+//                     FileOutputStream fos = new FileOutputStream(new File(tmpFileName));
+//                     fos.write(text.getBytes());
+//                     fos.flush();
+//                     fos.close();
+//
+//                     proc =
+//                             Runtime.getRuntime().exec(
+//                                     PerlEditorPlugin
+//                                             .getDefault()
+//                                             .getExecutablePreference()
+//                                             .trim()
+//                                             + " "
+//                                             + "-I"
+//                                             + ((IFileEditorInput) this.fTextEditor.getEditorInput())
+//                                                     .getFile()
+//                                                     .getLocation()
+//                                                     .makeAbsolute()
+//                                                     .removeLastSegments(1)
+//                                             + " "
+//                                             + PERL_CMD_EXT
+//                                             + " "
+//                                             + tmpFileName);
+//
+//                     InputStream in = proc.getErrorStream();
+//
+//                     StringBuffer content = new StringBuffer();
+//
+//                     byte[] buffer = new byte[1];
+//
+//                     int read;
+//                     while ((read = in.read(buffer)) > 0) {
+//                             content.append(new String(buffer));
+//                     }
+//                     in.close();
+//
+//                     //jjjjjjj
+//                     // DEBUG start
+//                     System.out.println("-----------------------------------------");
+//                     System.out.println("           OUTPUT");
+//                     System.out.println("-----------------------------------------");
+//                     System.out.println(content);
+//                     System.out.println("-----------------------------------------");
+//                     // DEBUG END
+//
+//                     String line = null;
+//                     List lines = new ArrayList();
+//                     int index;
+//
+//                     // Compare checksums
+//                     int hashCode = content.toString().hashCode();
+//
+//                     if (previousHashCode == hashCode) {
+//
+//                             return true;
+//                     }
+//
+//                     previousHashCode = hashCode;
+//
+//                     StringTokenizer st = new StringTokenizer(content.toString(), "\n");
+//
+//                     int lineCount = 0;
+//
+//                     while (st.hasMoreTokens()) {
+//                             line = st.nextToken();
+//                             if (line.indexOf("\r") != -1) {
+//                                     line = line.substring(0, line.indexOf("\r"));
+//                             }
+//
+//                             lines.add(line);
+//                             if (++lineCount >= maxErrorsShown) {
+//                                     break;
+//                             }
+//
+//                     }
+//
+//                     //Delete markers
+//                     resource.deleteMarkers(IMarker.PROBLEM, true, 1);
+//
+//                     // Markers have to be added in reverse order
+//                     // Otherwise lower line number will appear at the end of the list
+//                     for (int i = lines.size() - 1; i >= 0; i--) {
+//                             line = (String) lines.get(i);
+//
+//                             // If error message is not from temporary file, skip
+//                             if (line.indexOf(tmpFileName) == -1) {
+//                                     continue;
+//                             }
+//
+//                             // Delete filename from error message
+//                             StringBuffer lineSb = new StringBuffer(line);
+//                             replace(lineSb, tmpFileName + " ", "", true);
+//                             line = lineSb.toString();
+//
+//                             if ((index = line.indexOf(PERL_ERROR_INDICATOR)) != -1) {
+//
+//                                     // truncatedLIne is the stripped error-line up to the next " " after the line number if present
+//                                     // To avoid cluttering with other "." and "," which might occur in the error message
+//                                     String truncatedLine = line;
+//                                     if (truncatedLine
+//                                             .indexOf(" ", index + PERL_ERROR_INDICATOR.length() + 1)
+//                                             != -1) {
+//                                             truncatedLine =
+//                                                     truncatedLine.substring(
+//                                                             0,
+//                                                             truncatedLine.indexOf(
+//                                                                     " ",
+//                                                                     index + PERL_ERROR_INDICATOR.length() + 1));
+//                                     }
+//
+//                                     int endIndex;
+//                                     if ((endIndex = truncatedLine.indexOf(".", index)) == -1) {
+//                                             endIndex = truncatedLine.indexOf(",", index);
+//                                     }
+//
+//                                     if (endIndex == -1) {
+//                                             continue;
+//                                     }
+//
+//                                     String lineNr =
+//                                             truncatedLine.substring(
+//                                                     index + PERL_ERROR_INDICATOR.length(),
+//                                                     endIndex);
+//
+//                                     // If there is an addition to the error message
+//                                     if (i + 1 < lines.size()) {
+//                                             if (((String) lines.get(i + 1)).startsWith(" ")) {
+//                                                     line += " " + (String) lines.get(i + 1);
+//                                             }
+//                                     }
+//
+//                                     IMarker marker = resource.createMarker(IMarker.PROBLEM);
+//
+//                                     // Check if it's a warning
+//                                     boolean isWarning = false;
+//
+//                                     for (int x = 0; x < WARNING_STRINGS.length; x++) {
+//                                             if (truncatedLine.indexOf(WARNING_STRINGS[x]) != -1) {
+//                                                     isWarning = true;
+//                                             }
+//                                     }
+//
+//                                     if (isWarning) {
+//                                             marker.setAttribute(
+//                                                     IMarker.SEVERITY,
+//                                                     IMarker.SEVERITY_WARNING);
+//                                     } else {
+//                                             marker.setAttribute(
+//                                                     IMarker.SEVERITY,
+//                                                     IMarker.SEVERITY_ERROR);
+//                                     }
+//
+//                                     marker.setAttribute(IMarker.MESSAGE, line);
+//
+//                                     marker.setAttribute(
+//                                             IMarker.LINE_NUMBER,
+//                                             Integer.parseInt(lineNr));
+//
+//                                     Position pos =
+//                                             new Position(
+//                                                     fSourceViewer.getDocument().getLineOffset(
+//                                                             Integer.parseInt(lineNr) - 1));
+//                                     fSourceViewer.getAnnotationModel().addAnnotation(
+//                                             new MarkerAnnotation(marker),
+//                                             pos);
+//
+//                             }
+//                     }
+//
+//             } catch (Exception e) {
+//                     e.printStackTrace();
+//                     if (proc != null) {
+//                             killProcess(proc);
+//                     }
+//                     return false;
+//             } finally {
+//                     try {
+//                             //                              Delete tmp file
+//                             new File(tmpFileName).delete();
+//                     } catch (Exception ex) {
+//                             ex.printStackTrace();
+//                     }
+//             }
+
+               return true;
+
+       }
+
+  /**
+    * Finds the file that's currently opened in the PHP Text Editor
+    */
+   protected IFile getPHPFile(IEditorInput editorInput) {
+     if (editorInput instanceof IFileEditorInput)
+       return ((IFileEditorInput) editorInput).getFile();
+
+     return null;
+   }
+    
+   protected void parse(IFile fileToParse, InputStream iStream) {
+
+     StringBuffer buf = new StringBuffer();
+     int c0;
+     try {
+       while ((c0 = iStream.read()) != (-1)) {
+         buf.append((char) c0);
+       }
+     } catch (IOException e) {
+       return;
+     }
+     String input = buf.toString();
+
+     PHPParserSuperclass parser = PHPParserManager.getParser(fileToParse);
+     try {
+       parser.parse(input);
+     } catch (CoreException e) {
+     }
+   }
+   
+       private void killProcess(Process proc) {
+               while (true) {
+                       try {
+                               proc.destroy();
+                               proc.exitValue();
+                       } catch (Exception ex) {
+
+                               continue;
+                       }
+                       break;
+               }
+       }
+
+       // Replaces all instances of the String o with the String n in the
+       // StringBuffer orig if all is true, or only the first instance if all is false.
+       private static void replace(
+               StringBuffer orig,
+               String o,
+               String n,
+               boolean all) {
+               if (orig == null || o == null || o.length() == 0 || n == null)
+                       throw new IllegalArgumentException("Null or zero-length String");
+
+               int i = 0;
+
+               while (i + o.length() <= orig.length()) {
+                       if (orig.substring(i, i + o.length()).equals(o)) {
+                               orig.replace(i, i + o.length(), n);
+                               if (!all)
+                                       break;
+                               else
+                                       i += n.length();
+                       } else
+                               i++;
+               }
+       }
+}