improved include detection
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / ui / text / JavaTextTools.java
1 package net.sourceforge.phpdt.ui.text;
2
3 /*
4  * (c) Copyright IBM Corp. 2000, 2001.
5  * All Rights Reserved.
6  */
7
8 import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
9 import net.sourceforge.phpdt.internal.ui.text.JavaColorManager;
10 import net.sourceforge.phpdt.internal.ui.text.phpdoc.PHPDocCodeScanner;
11 import net.sourceforge.phpeclipse.IPreferenceConstants;
12 import net.sourceforge.phpeclipse.phpeditor.php.HTMLCodeScanner;
13 import net.sourceforge.phpeclipse.phpeditor.php.PHPCodeScanner;
14 import net.sourceforge.phpeclipse.phpeditor.php.PHPPartitionScanner;
15 import net.sourceforge.phpeclipse.phpeditor.php.SmartyCodeScanner;
16 import net.sourceforge.phpeclipse.phpeditor.php.SmartyDocCodeScanner;
17
18 import org.eclipse.core.resources.IFile;
19 import org.eclipse.core.runtime.Preferences;
20 import org.eclipse.jface.preference.IPreferenceStore;
21 import org.eclipse.jface.text.IDocument;
22 import org.eclipse.jface.text.IDocumentExtension3;
23 import org.eclipse.jface.text.IDocumentPartitioner;
24 import org.eclipse.jface.text.rules.DefaultPartitioner;
25 import org.eclipse.jface.text.rules.IPartitionTokenScanner;
26 import org.eclipse.jface.text.rules.RuleBasedScanner;
27 import org.eclipse.jface.util.IPropertyChangeListener;
28 import org.eclipse.jface.util.PropertyChangeEvent;
29 import org.eclipse.ui.part.FileEditorInput;
30 //
31 //import org.phpeclipse.phpdt.internal.ui.text.FastJavaPartitionScanner;
32 //import org.phpeclipse.phpdt.internal.ui.text.JavaColorManager;
33 //import org.phpeclipse.phpdt.internal.ui.text.JavaPartitionScanner;
34 //import org.phpeclipse.phpdt.internal.ui.text.SingleTokenJavaScanner;
35 //import org.phpeclipse.phpdt.internal.ui.text.php.JavaCodeScanner;
36 //import org.phpeclipse.phpdt.internal.ui.text.phpdoc.JavaDocScanner;
37
38 /**
39  * Tools required to configure a Java text viewer. 
40  * The color manager and all scanner exist only one time, i.e.
41  * the same instances are returned to all clients. Thus, clients
42  * share those tools.
43  * <p>
44  * This class may be instantiated; it is not intended to be subclassed.
45  * </p>
46  */
47 public class JavaTextTools {
48
49   private static PHPPartitionScanner HTML_PARTITION_SCANNER = null;
50
51   private static PHPPartitionScanner PHP_PARTITION_SCANNER = null;
52   private static PHPPartitionScanner SMARTY_PARTITION_SCANNER = null;
53
54   // private final static String[] TYPES= new String[] { PHPPartitionScanner.PHP, PHPPartitionScanner.JAVA_DOC, PHPPartitionScanner.JAVA_MULTILINE_COMMENT };
55   private final static String[] TYPES =
56     new String[] {
57       IPHPPartitions.PHP_PARTITIONING,
58       IPHPPartitions.PHP_PHPDOC_COMMENT,
59       IPHPPartitions.HTML,
60       IPHPPartitions.HTML_MULTILINE_COMMENT,
61       IPHPPartitions.JAVASCRIPT,
62       IPHPPartitions.CSS,
63       IPHPPartitions.SMARTY,
64       IPHPPartitions.SMARTY_MULTILINE_COMMENT };
65   private static PHPPartitionScanner XML_PARTITION_SCANNER = null;
66
67   /**
68    * This tools' preference listener. 
69    */
70   private class PreferenceListener implements IPropertyChangeListener, Preferences.IPropertyChangeListener {
71     public void propertyChange(PropertyChangeEvent event) {
72       adaptToPreferenceChange(event);
73     }
74     public void propertyChange(Preferences.PropertyChangeEvent event) {
75       adaptToPreferenceChange(
76         new PropertyChangeEvent(event.getSource(), event.getProperty(), event.getOldValue(), event.getNewValue()));
77     }
78   };
79
80   /** The color manager */
81   private JavaColorManager fColorManager;
82   /** The PHP source code scanner */
83   private PHPCodeScanner fCodeScanner;
84   /** The PHP multiline comment scanner */
85   private SingleTokenPHPScanner fMultilineCommentScanner;
86   /** The Java singleline comment scanner */
87   private SingleTokenPHPScanner fSinglelineCommentScanner;
88   /** The Java string scanner */
89   private SingleTokenPHPScanner fStringScanner;
90   /** The PHPDoc scanner */
91   private PHPDocCodeScanner fPHPDocScanner;
92   /** The HTML scanner */
93   private HTMLCodeScanner fHTMLScanner;
94   /** The Smarty scanner */
95   private SmartyCodeScanner fSmartyScanner;
96   /** The SmartyDoc scanner */
97   private SmartyDocCodeScanner fSmartyDocScanner;
98   /** The Java partitions scanner */
99   private PHPPartitionScanner fPartitionScanner;
100
101   /** The preference store */
102   private IPreferenceStore fPreferenceStore;
103   /**
104    * The core preference store.
105    * @since 2.1
106    */
107   private Preferences fCorePreferenceStore;
108   /** The preference change listener */
109   private PreferenceListener fPreferenceListener = new PreferenceListener();
110
111   /**
112    * Creates a new Java text tools collection.
113    * 
114    * @param store the preference store to initialize the text tools. The text tool
115    * instance installs a listener on the passed preference store to adapt itself to 
116    * changes in the preference store. In general <code>PreferenceConstants.
117    * getPreferenceStore()</code> shoould be used to initialize the text tools.
118    * 
119    * @see org.phpeclipse.phpdt.ui.PreferenceConstants#getPreferenceStore()
120    * @since 2.0
121    */
122   public JavaTextTools(IPreferenceStore store) {
123     fPreferenceStore = store;
124     fPreferenceStore.addPropertyChangeListener(fPreferenceListener);
125
126     fColorManager = new JavaColorManager();
127     fCodeScanner = new PHPCodeScanner(fColorManager, store);
128     fMultilineCommentScanner = new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_MULTILINE_COMMENT);
129     fSinglelineCommentScanner = new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_SINGLELINE_COMMENT);
130     fStringScanner = new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_STRING);
131     fPHPDocScanner = new PHPDocCodeScanner(fColorManager, store);
132     fHTMLScanner = new HTMLCodeScanner(fColorManager, store);
133     fSmartyScanner = new SmartyCodeScanner(fColorManager, store);
134     fSmartyDocScanner = new SmartyDocCodeScanner(fColorManager, store);
135 //    fPartitionScanner = new FastJavaPartitionScanner();
136     fPartitionScanner = new PHPPartitionScanner();
137   }
138
139   /**
140    * Creates a new Java text tools collection.
141    * 
142    * @param store the preference store to initialize the text tools. The text tool
143    *                    instance installs a listener on the passed preference store to adapt itself to 
144    *                    changes in the preference store. In general <code>PreferenceConstants.
145    *                    getPreferenceStore()</code> shoould be used to initialize the text tools.
146    * @param coreStore optional preference store to initialize the text tools. The text tool
147    *                    instance installs a listener on the passed preference store to adapt itself to 
148    *                    changes in the preference store.
149    * @param autoDisposeOnDisplayDispose         if <code>true</code>  the color manager
150    *                    automatically disposes all managed colors when the current display gets disposed
151    *                    and all calls to {@link org.eclipse.jface.text.source.ISharedTextColors#dispose()} are ignored.
152    * @see org.eclipse.jdt.ui.PreferenceConstants#getPreferenceStore()
153    * @since 2.1
154    */
155   public JavaTextTools(IPreferenceStore store, Preferences coreStore, boolean autoDisposeOnDisplayDispose) {
156     fPreferenceStore = store;
157     fPreferenceStore.addPropertyChangeListener(fPreferenceListener);
158
159     fCorePreferenceStore = coreStore;
160     if (fCorePreferenceStore != null)
161       fCorePreferenceStore.addPropertyChangeListener(fPreferenceListener);
162
163     fColorManager = new JavaColorManager(autoDisposeOnDisplayDispose);
164     fCodeScanner = new PHPCodeScanner(fColorManager, store);
165     fMultilineCommentScanner = new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_MULTILINE_COMMENT);
166     fSinglelineCommentScanner = new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_SINGLELINE_COMMENT);
167     fStringScanner = new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_STRING);
168     fPHPDocScanner = new PHPDocCodeScanner(fColorManager, store);
169     fHTMLScanner = new HTMLCodeScanner(fColorManager, store);
170     fSmartyScanner = new SmartyCodeScanner(fColorManager, store);
171     fSmartyDocScanner = new SmartyDocCodeScanner(fColorManager, store);
172   //  fPartitionScanner = new FastJavaPartitionScanner();
173     fPartitionScanner = new PHPPartitionScanner();
174   }
175
176   /**
177    * Disposes all the individual tools of this tools collection.
178    */
179   public void dispose() {
180
181     fCodeScanner = null;
182     fMultilineCommentScanner = null;
183     fSinglelineCommentScanner = null;
184     fStringScanner = null;
185     fPHPDocScanner = null;
186     fPartitionScanner = null;
187
188     if (fColorManager != null) {
189       fColorManager.dispose();
190       fColorManager = null;
191     }
192
193     if (fPreferenceStore != null) {
194       fPreferenceStore.removePropertyChangeListener(fPreferenceListener);
195       fPreferenceStore = null;
196
197       if (fCorePreferenceStore != null) {
198         fCorePreferenceStore.removePropertyChangeListener(fPreferenceListener);
199         fCorePreferenceStore = null;
200       }
201
202       fPreferenceListener = null;
203     }
204   }
205
206   /**
207    * Returns the color manager which is used to manage
208    * any Java-specific colors needed for such things like syntax highlighting.
209    *
210    * @return the color manager to be used for Java text viewers
211    */
212   public IColorManager getColorManager() {
213     return fColorManager;
214   }
215
216   /**
217    * Returns a scanner which is configured to scan Java source code.
218    *
219    * @return a Java source code scanner
220    */
221   public RuleBasedScanner getCodeScanner() {
222     return fCodeScanner;
223   }
224
225   /**
226    * Returns a scanner which is configured to scan Java multiline comments.
227    *
228    * @return a Java multiline comment scanner
229    * 
230    * @since 2.0
231    */
232   public RuleBasedScanner getMultilineCommentScanner() {
233     return fMultilineCommentScanner;
234   }
235
236   /**
237    * Returns a scanner which is configured to scan HTML code.
238    *
239    * @return a HTML scanner
240    * 
241    * @since 2.0
242    */
243   public RuleBasedScanner getHTMLScanner() {
244     return fHTMLScanner;
245   }
246
247   /**
248    * Returns a scanner which is configured to scan Smarty code.
249    *
250    * @return a Smarty scanner
251    * 
252    * @since 2.0
253    */
254   public RuleBasedScanner getSmartyScanner() {
255     return fSmartyScanner;
256   }
257
258   /**
259          * Returns a scanner which is configured to scan Smarty code.
260          *
261          * @return a Smarty scanner
262          * 
263          * @since 2.0
264          */
265   public RuleBasedScanner getSmartyDocScanner() {
266     return fSmartyDocScanner;
267   }
268   /**
269    * Returns a scanner which is configured to scan Java singleline comments.
270    *
271    * @return a Java singleline comment scanner
272    * 
273    * @since 2.0
274    */
275   public RuleBasedScanner getSinglelineCommentScanner() {
276     return fSinglelineCommentScanner;
277   }
278
279   /**
280    * Returns a scanner which is configured to scan Java strings.
281    *
282    * @return a Java string scanner
283    * 
284    * @since 2.0
285    */
286   public RuleBasedScanner getStringScanner() {
287     return fStringScanner;
288   }
289
290   /**
291    * Returns a scanner which is configured to scan JavaDoc compliant comments.
292    * Notes that the start sequence "/**" and the corresponding end sequence
293    * are part of the JavaDoc comment.
294    *
295    * @return a JavaDoc scanner
296    */
297   public RuleBasedScanner getJavaDocScanner() {
298     return fPHPDocScanner;
299   }
300
301   /**
302    * Returns a scanner which is configured to scan 
303    * Java-specific partitions, which are multi-line comments,
304    * JavaDoc comments, and regular Java source code.
305    *
306    * @return a Java partition scanner
307    */
308   public IPartitionTokenScanner getPartitionScanner() {
309     return fPartitionScanner;
310   }
311
312   /**
313    * Factory method for creating a PHP-specific document partitioner
314    * using this object's partitions scanner. This method is a 
315    * convenience method.
316    *
317    * @return a newly created Java document partitioner
318    */
319   public IDocumentPartitioner createDocumentPartitioner() {
320     return createDocumentPartitioner(".php");
321   }
322
323   /**
324    * Factory method for creating a PHP-specific document partitioner
325    * using this object's partitions scanner. This method is a 
326    * convenience method.
327    *
328    * @return a newly created Java document partitioner
329    */
330   public IDocumentPartitioner createDocumentPartitioner(String extension) {
331
332     //    String[] types =
333     //      new String[] {
334     //        FastJavaPartitionScanner.JAVA_DOC,
335     //        FastJavaPartitionScanner.JAVA_MULTI_LINE_COMMENT,
336     //        FastJavaPartitionScanner.JAVA_SINGLE_LINE_COMMENT,
337     //        FastJavaPartitionScanner.JAVA_STRING };
338     //
339     //    return new DefaultPartitioner(getPartitionScanner(), types);
340     IDocumentPartitioner partitioner = null;
341     //  System.out.println(extension);
342     if (extension.equalsIgnoreCase(".html") || extension.equalsIgnoreCase(".htm")) {
343       // html
344       partitioner = createHTMLPartitioner();
345     } else if (extension.equalsIgnoreCase(".xml")) {
346       // xml
347       partitioner = createXMLPartitioner();
348     } else if (extension.equalsIgnoreCase(".js")) {
349       // javascript
350       partitioner = createJavaScriptPartitioner();
351     } else if (extension.equalsIgnoreCase(".css")) {
352       // cascading style sheets
353       partitioner = createCSSPartitioner();
354     } else if (extension.equalsIgnoreCase(".tpl")) {
355       // smarty ?
356       partitioner = createSmartyPartitioner();
357     } else if (extension.equalsIgnoreCase(".inc")) {
358       // php include files ?
359       partitioner = createIncludePartitioner();
360     }
361
362     if (partitioner == null) {
363       partitioner = createPHPPartitioner();
364     }
365
366     return partitioner;
367   }
368         /**
369          * Sets up the Java document partitioner for the given document for the default partitioning.
370          * 
371          * @param document the document to be set up
372          * @since 3.0
373          */
374         public void setupJavaDocumentPartitioner(IDocument document) {
375                 setupJavaDocumentPartitioner(document, IDocumentExtension3.DEFAULT_PARTITIONING,null);
376         }
377         /**
378          * Sets up the Java document partitioner for the given document for the given partitioning.
379          * @param document the document to be set up
380          * @param partitioning the document partitioning
381          * @param element TODO
382          * 
383          * @since 3.0
384          */
385         public void setupJavaDocumentPartitioner(IDocument document, String partitioning, Object element) {
386                 IDocumentPartitioner partitioner = createDocumentPartitioner(".php");
387                          
388 //              if (document instanceof IDocumentExtension3) {
389 //                      IDocumentExtension3 extension3= (IDocumentExtension3) document;
390 //                      extension3.setDocumentPartitioner(partitioning, partitioner);
391 //              } else {
392                         document.setDocumentPartitioner(partitioner);
393 //              }
394                 partitioner.connect(document);
395         }
396         public void setupHTMLDocumentPartitioner(IDocument document, String partitioning, Object element) {
397                 IDocumentPartitioner partitioner = createDocumentPartitioner(".html");
398                          
399 //              if (document instanceof IDocumentExtension3) {
400 //                      IDocumentExtension3 extension3= (IDocumentExtension3) document;
401 //                      extension3.setDocumentPartitioner(partitioning, partitioner);
402 //              } else {
403                         document.setDocumentPartitioner(partitioner);
404 //              }
405                 partitioner.connect(document);
406         }
407         public void setupSmartyDocumentPartitioner(IDocument document, String partitioning, Object element) {
408                 IDocumentPartitioner partitioner = createDocumentPartitioner(".tpl");
409                          
410 //              if (document instanceof IDocumentExtension3) {
411 //                      IDocumentExtension3 extension3= (IDocumentExtension3) document;
412 //                      extension3.setDocumentPartitioner(partitioning, partitioner);
413 //              } else {
414                         document.setDocumentPartitioner(partitioner);
415 //              }
416                 partitioner.connect(document);
417         }
418   /**
419    * Returns the names of the document position categories used by the document
420    * partitioners created by this object to manage their partition information.
421    * If the partitioners don't use document position categories, the returned
422    * result is <code>null</code>.
423    *
424    * @return the partition managing position categories or <code>null</code> 
425    *                    if there is none
426    */
427   public String[] getPartitionManagingPositionCategories() {
428     return new String[] { DefaultPartitioner.CONTENT_TYPES_CATEGORY };
429   }
430
431   /**
432    * Determines whether the preference change encoded by the given event
433    * changes the behavior of one its contained components.
434    * 
435    * @param event the event to be investigated
436    * @return <code>true</code> if event causes a behavioral change
437    * 
438    * @since 2.0
439    */
440   public boolean affectsBehavior(PropertyChangeEvent event) {
441     return fCodeScanner.affectsBehavior(event)
442       || fMultilineCommentScanner.affectsBehavior(event)
443       || fSinglelineCommentScanner.affectsBehavior(event)
444       || fStringScanner.affectsBehavior(event)
445       || fPHPDocScanner.affectsBehavior(event);
446   }
447
448   /**
449    * Adapts the behavior of the contained components to the change
450    * encoded in the given event.
451    * 
452    * @param event the event to which to adapt
453    * @since 2.0
454    */
455   protected void adaptToPreferenceChange(PropertyChangeEvent event) {
456     if (fCodeScanner.affectsBehavior(event))
457       fCodeScanner.adaptToPreferenceChange(event);
458     if (fMultilineCommentScanner.affectsBehavior(event))
459       fMultilineCommentScanner.adaptToPreferenceChange(event);
460     if (fSinglelineCommentScanner.affectsBehavior(event))
461       fSinglelineCommentScanner.adaptToPreferenceChange(event);
462     if (fStringScanner.affectsBehavior(event))
463       fStringScanner.adaptToPreferenceChange(event);
464     if (fPHPDocScanner.affectsBehavior(event))
465       fPHPDocScanner.adaptToPreferenceChange(event);
466   }
467
468   /**
469          * Return a partitioner for .html files.
470          */
471   private static IDocumentPartitioner createHTMLPartitioner() {
472     return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES);
473   }
474
475   private static IDocumentPartitioner createIncludePartitioner() {
476     return new DefaultPartitioner(getPHPPartitionScanner(), TYPES);
477   }
478
479   private static IDocumentPartitioner createJavaScriptPartitioner() {
480     return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES);
481   }
482
483   /**
484         * Return a partitioner for .php files.
485         */
486   private static IDocumentPartitioner createPHPPartitioner() {
487     return new DefaultPartitioner(getPHPPartitionScanner(), TYPES);
488   }
489
490   private static IDocumentPartitioner createSmartyPartitioner() {
491     return new DefaultPartitioner(getSmartyPartitionScanner(), TYPES);
492   }
493
494   private static IDocumentPartitioner createXMLPartitioner() {
495     return new DefaultPartitioner(getXMLPartitionScanner(), TYPES);
496   }
497
498   private static IDocumentPartitioner createCSSPartitioner() {
499     return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES);
500   }
501   /**
502         * Return a scanner for creating html partitions.
503         */
504   private static PHPPartitionScanner getHTMLPartitionScanner() {
505     if (HTML_PARTITION_SCANNER == null)
506       HTML_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitions.HTML_FILE);
507     return HTML_PARTITION_SCANNER;
508   }
509   /**
510         * Return a scanner for creating php partitions.
511         */
512   private static PHPPartitionScanner getPHPPartitionScanner() {
513     if (PHP_PARTITION_SCANNER == null)
514       PHP_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitions.PHP_FILE);
515     return PHP_PARTITION_SCANNER;
516   }
517
518   /**
519         * Return a scanner for creating smarty partitions.
520         */
521   private static PHPPartitionScanner getSmartyPartitionScanner() {
522     if (SMARTY_PARTITION_SCANNER == null)
523       SMARTY_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitions.SMARTY_FILE);
524     return SMARTY_PARTITION_SCANNER;
525   }
526
527   /**
528         * Return a scanner for creating xml partitions.
529         */
530   private static PHPPartitionScanner getXMLPartitionScanner() {
531     if (XML_PARTITION_SCANNER == null)
532       XML_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitions.XML_FILE);
533     return XML_PARTITION_SCANNER;
534   }
535
536 }