Fixed bug in CodeFormatter; for partial formatting select complete <?php ... ?> range
[phpeclipse.git] / archive / net.sourceforge.phpeclipse.jtidy / src / net / sourceforge / phpdt / tidy / actions / AbstractJTidyAction.java
1 /**
2  * Created on 13.01.2003 by Jan Schulz
3  */
4 package net.sourceforge.phpdt.tidy.actions;
5
6 import java.io.ByteArrayInputStream;
7 import java.io.ByteArrayOutputStream;
8 import java.io.InputStream;
9 import java.util.Iterator;
10
11 import net.sourceforge.phpdt.tidy.JtidyPlugin;
12
13 import org.eclipse.core.resources.IFile;
14 import org.eclipse.core.resources.IMarker;
15 import org.eclipse.core.resources.IResource;
16 import org.eclipse.core.runtime.CoreException;
17 import org.eclipse.jface.action.IAction;
18 import org.eclipse.jface.dialogs.MessageDialog;
19 import org.eclipse.jface.text.IDocument;
20 import org.eclipse.jface.viewers.ISelection;
21 import org.eclipse.jface.viewers.IStructuredSelection;
22 import org.eclipse.ui.IEditorPart;
23 import org.eclipse.ui.editors.text.TextEditor;
24 import org.eclipse.ui.texteditor.ITextEditor;
25
26 /**
27  * @author jan
28  * @since 13.01.2003
29  */
30 public abstract class AbstractJTidyAction {
31   private ITextEditor fTextEditor = null;
32   private IStructuredSelection fSelection = null;
33
34   /**
35    * Parses the given stream with a Tidy Instance, which belongs to this
36    * IFile. Problems will be marked on this file.
37    * @param in
38    * @param file
39    * @return InputStream
40    */
41   protected byte[] parseStreamOfFile(InputStream in, IFile file) {
42     deleteTidyMarker(file);
43     ByteArrayOutputStream out = new ByteArrayOutputStream();
44     JtidyPlugin.getTidyInstance(file).parse(file, in, out);
45     return out.toByteArray();
46
47   }
48
49   /**
50    * Deletes all JTidy Marker of this File
51    * 
52    * @param file
53    */
54   protected void deleteTidyMarker(IFile file) {
55     try {
56       IMarker[] markers = file.findMarkers(null, false, IResource.DEPTH_ZERO);
57       for (int i = 0; i < markers.length; i++) {
58         IMarker marker = markers[i];
59         if (marker.getAttribute(JtidyPlugin.MARKER_NAME) != null) {
60           marker.delete();
61         }
62       }
63     } catch (CoreException e) {
64       //LOGGING
65     }
66   }
67
68   /**
69    * Parses the Document with Tidy.
70    */
71   protected void parseDocument(boolean writeBack) throws ParseFailedException {
72     IDocument doku = fTextEditor.getDocumentProvider().getDocument(fTextEditor.getEditorInput());
73     assertNotNull(doku);
74     String content = doku.get();
75     IFile file = (IFile) fTextEditor.getEditorInput().getAdapter(IFile.class);
76     assertNotNull(file);
77     byte[] ret = parseStreamOfFile(new ByteArrayInputStream(content.getBytes()), file);
78     if (writeBack) {
79       if (ret.length != 0) {
80         String cleanedContent = new String(ret);
81         doku.set(cleanedContent);
82       } else {
83         displayError(
84           "Formatting skipped",
85           "This document has errors that must be fixed before using HTML Tidy to generate a tidied up version.");
86       }
87
88     }
89   }
90
91   /**
92    * Throws a ParseFailedException, if the given obj is null
93    * 
94    * @param obj
95    * @throws ParseFailedException
96    */
97   protected void assertNotNull(Object obj) throws ParseFailedException {
98     if (obj == null) {
99       throw new ParseFailedException("A expected 'non-null' Value was null");
100     }
101   }
102
103   /**
104    * Updates the enable state of the parent action
105    * @param action
106    */
107   protected void updateParent(IAction action) {
108     action.setEnabled(fTextEditor != null || fSelection != null);
109   }
110
111   /**
112    * Parses all Files in the given selection...
113    */
114   protected void parseSelection(boolean writeBack) {
115     Iterator iterator = null;
116     iterator = fSelection.iterator();
117     while (iterator.hasNext()) {
118       //  obj => selected object in the view
119       Object obj = iterator.next();
120
121       // is it a resource
122       if (obj instanceof IResource) {
123         IResource resource = (IResource) obj;
124
125         // check if it's a file resource
126         switch (resource.getType()) {
127
128           case IResource.FILE :
129             // single file:
130             IFile file = (IFile) resource;
131
132             InputStream in;
133             try {
134               in = file.getContents();
135               byte[] ret = parseStreamOfFile(in, file);
136
137               if (writeBack) {
138                 if (ret.length != 0) {
139                   InputStream source = new ByteArrayInputStream(ret);
140                   file.setContents(source, IFile.KEEP_HISTORY, null);
141
142                 } else {
143                   displayError(
144                     "Formatting skipped",
145                     "This document has errors that must be fixed before using HTML Tidy to generate a tidied up version.");
146                 }
147               }
148             } catch (CoreException e) {
149             }
150         }
151       }
152     }
153   }
154   /**
155    * Method error.
156    * @param string
157    * @param string1
158    */
159   private void error(String lable, String message) {
160
161     // TODO:
162   }
163
164   /**
165          * Opens an error dialog to display the given message.
166          *
167          * @param message the error message to show
168          */
169   private void displayError(final String title, final String message) {
170     MessageDialog.openError(null, title, message);
171 //    final Shell parentShell = getShell();
172 //    parentShell.getDisplay().syncExec(new Runnable() {
173 //      public void run() {
174 //        MessageDialog.openError(parentShell, lable, message);
175 //      }
176 //    });
177   }
178 //  /**
179 //   * Method getShell.
180 //   * @return Shell
181 //   */
182 //  protected abstract Shell getShell();
183
184   /**
185    * Updates the Selection: if the given selection is of type
186    * IStruckturedSelection, fSection is set to this, otehrwise the field is
187    * set to null.
188    * @param sel
189    */
190   protected void updateSelection(ISelection sel) {
191     if (sel instanceof IStructuredSelection) {
192       fSelection = (IStructuredSelection) sel;
193       // REVISIT: further determination of types?
194     } else {
195       fSelection = null;
196     }
197   }
198
199   /**
200    * If the given WorkbenchPart is of type ITextEditor, fTextEditor is set to
201    * this value, otherwise to null
202    * 
203    */
204   protected void updateEditor(IEditorPart part) {
205     if (part instanceof ITextEditor) {
206       fTextEditor = (ITextEditor) part;
207     } else {
208       if (part instanceof TextEditor) {
209         fTextEditor = (TextEditor) part;
210       } else {
211         fTextEditor = null;
212       }
213     }
214   }
215
216   protected IEditorPart getEditor() {
217     return fTextEditor;
218   }
219 }