Fix hover functionality.
[phpeclipse.git] / net.sourceforge.phpeclipse.ui / src / net / sourceforge / phpeclipse / ui / WebUI.java
1 /*
2  * Copyright (c) 2004 Christopher Lenz and others
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  *
8  * Contributors:
9  *     Christopher Lenz - initial implementation
10  *
11  * $Id: WebUI.java,v 1.11 2007-11-08 01:37:06 scorphus Exp $
12  */
13
14 package net.sourceforge.phpeclipse.ui;
15
16 import org.eclipse.jface.resource.JFaceResources;
17 import java.io.File;
18 import java.io.IOException;
19 //import java.io.InputStream;
20 import java.net.URL;
21 //import java.util.Enumeration;
22 import java.util.HashMap;
23 //import java.util.PropertyResourceBundle;
24
25 //import net.sourceforge.phpdt.core.JavaCore;
26 import net.sourceforge.phpdt.core.IBuffer;
27 import net.sourceforge.phpdt.core.ICompilationUnit;
28 import net.sourceforge.phpdt.core.IJavaElement;
29 import net.sourceforge.phpdt.core.WorkingCopyOwner;
30 import net.sourceforge.phpdt.internal.core.JavaModelManager;
31 import net.sourceforge.phpdt.internal.core.util.Util;
32 import net.sourceforge.phpdt.internal.corext.template.php.CodeTemplateContextType;
33 import net.sourceforge.phpdt.internal.corext.template.php.HTMLContextType;
34 import net.sourceforge.phpdt.internal.corext.template.php.JavaContextType;
35 import net.sourceforge.phpdt.internal.corext.template.php.JavaDocContextType;
36 import net.sourceforge.phpdt.internal.ui.IJavaStatusConstants;
37 import net.sourceforge.phpdt.internal.ui.JavaElementAdapterFactory;
38 import net.sourceforge.phpdt.internal.ui.ResourceAdapterFactory;
39 import net.sourceforge.phpdt.internal.ui.preferences.MembersOrderPreferenceCache;
40 import net.sourceforge.phpdt.internal.ui.preferences.MockupPreferenceStore;
41 import net.sourceforge.phpdt.internal.ui.text.PreferencesAdapter;
42 import net.sourceforge.phpdt.internal.ui.text.folding.JavaFoldingStructureProviderRegistry;
43 import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaEditorTextHoverDescriptor;
44 import net.sourceforge.phpdt.internal.ui.viewsupport.ImageDescriptorRegistry;
45 import net.sourceforge.phpdt.internal.ui.viewsupport.ProblemMarkerManager;
46 import net.sourceforge.phpdt.ui.IContextMenuConstants;
47 import net.sourceforge.phpdt.ui.IWorkingCopyManager;
48 import net.sourceforge.phpdt.ui.text.JavaTextTools;
49 import net.sourceforge.phpdt.ui.PreferenceConstants;
50 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
51 import net.sourceforge.phpeclipse.builder.ExternalEditorInput;
52 import net.sourceforge.phpeclipse.builder.ExternalStorageDocumentProvider;
53 import net.sourceforge.phpeclipse.builder.FileStorage;
54 import net.sourceforge.phpeclipse.builder.IdentifierIndexManager;
55 import net.sourceforge.phpeclipse.DocumentAdapter;
56 import net.sourceforge.phpeclipse.phpeditor.ICompilationUnitDocumentProvider;
57 import net.sourceforge.phpeclipse.phpeditor.PHPDocumentProvider;
58 //import net.sourceforge.phpeclipse.phpeditor.PHPSyntaxRdr;
59 import net.sourceforge.phpeclipse.phpeditor.WorkingCopyManager;
60 //import net.sourceforge.phpeclipse.phpeditor.util.PHPColorProvider;
61
62
63 import net.sourceforge.phpeclipse.ui.templates.template.HTMLTemplateContextType;
64 //import net.sourceforge.phpdt.internal.corext.template.php.HTMLContextType;
65
66 import net.sourceforge.phpeclipse.ui.templates.template.JSTemplateContextType;
67 import net.sourceforge.phpeclipse.ui.templates.template.SmartyTemplateContextType;
68 import net.sourceforge.phpeclipse.ui.templates.template.XMLTemplateContextType;
69
70 import org.eclipse.core.resources.IFile;
71 import org.eclipse.core.resources.IProject;
72 import org.eclipse.core.resources.IResource;
73 import org.eclipse.core.resources.IResourceChangeEvent;
74 import org.eclipse.core.resources.ISavedState;
75 import org.eclipse.core.resources.IWorkspace;
76 import org.eclipse.core.resources.ResourcesPlugin;
77 import org.eclipse.core.resources.WorkspaceJob;
78 import org.eclipse.core.runtime.CoreException;
79 import org.eclipse.core.runtime.IAdapterManager;
80 import org.eclipse.core.runtime.IConfigurationElement;
81 import org.eclipse.core.runtime.IPath;
82 import org.eclipse.core.runtime.IProgressMonitor;
83 import org.eclipse.core.runtime.IStatus;
84 import org.eclipse.core.runtime.Path;
85 import org.eclipse.core.runtime.Platform;
86 //import org.eclipse.core.runtime.Platform;
87 import org.eclipse.core.runtime.Status;
88 import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
89 import org.eclipse.core.runtime.Preferences.PropertyChangeEvent;
90 import org.eclipse.core.runtime.jobs.Job;
91 import org.eclipse.jface.action.GroupMarker;
92 import org.eclipse.jface.action.IMenuManager;
93 import org.eclipse.jface.action.Separator;
94 import org.eclipse.jface.preference.IPreferenceStore;
95 import org.eclipse.jface.preference.PreferenceConverter;
96 //import org.eclipse.jface.preference.PreferenceConverter;
97 import org.eclipse.jface.resource.ImageDescriptor;
98 import org.eclipse.jface.resource.ImageRegistry;
99 //import org.eclipse.jface.resource.JFaceResources;
100 import org.eclipse.jface.text.BadLocationException;
101 import org.eclipse.jface.text.IDocument;
102 import org.eclipse.jface.text.templates.ContextTypeRegistry;
103 import org.eclipse.jface.text.templates.persistence.TemplateStore;
104 //import org.eclipse.swt.graphics.RGB;
105 import org.eclipse.swt.widgets.Shell;
106 import org.eclipse.ui.IEditorDescriptor;
107 import org.eclipse.ui.IEditorInput;
108 import org.eclipse.ui.IEditorPart;
109 import org.eclipse.ui.IEditorRegistry;
110 import org.eclipse.ui.IWorkbench;
111 import org.eclipse.ui.IWorkbenchPage;
112 import org.eclipse.ui.IWorkbenchWindow;
113 import org.eclipse.ui.PlatformUI;
114 import org.eclipse.ui.editors.text.EditorsUI;
115 import org.eclipse.ui.editors.text.templates.ContributionContextTypeRegistry;
116 import org.eclipse.ui.editors.text.templates.ContributionTemplateStore;
117 import org.eclipse.ui.ide.IDE;
118 import org.eclipse.ui.plugin.AbstractUIPlugin;
119 import org.eclipse.ui.texteditor.ChainedPreferenceStore;
120 import org.eclipse.ui.texteditor.ConfigurationElementSorter;
121 import org.eclipse.ui.texteditor.IDocumentProvider;
122 import org.eclipse.ui.texteditor.ITextEditor;
123 import org.osgi.framework.BundleContext;
124
125 /**
126  * The web development tools UI plugin.
127  */
128 public class WebUI extends AbstractUIPlugin implements IPreferenceConstants {
129
130         public static final String PLUGIN_ID = "net.sourceforge.phpeclipse.ui";
131
132         public static final String EDITOR_ID = WebUI.PLUGIN_ID + ".PHPUnitEditor";
133
134
135         /**
136          * The key to store customized templates.
137          * 
138          * @since 3.0
139          */
140         private static final String TEMPLATES_KEY = "net.sourceforge.phpdt.ui.text.custom_templates"; //$NON-NLS-1$
141
142         /**
143          * The key to store customized code templates.
144          * 
145          * @since 3.0
146          */
147         private static final String CODE_TEMPLATES_KEY = "net.sourceforge.phpdt.ui.text.custom_code_templates"; //$NON-NLS-1$
148
149         
150         
151         
152         
153     private static final String CUSTOM_TEMPLATES_KEY = "net.sourceforge.phpeclipse.ui.templates"; //$NON-NLS-1$
154
155         /**
156          * The key to store customized code templates.
157          * 
158          * @since 3.0
159          */
160 //      private static final String CODE_TEMPLATES_KEY = "net.sourceforge.phpdt.ui.text.custom_code_templates"; //$NON-NLS-1$
161         /**
162          * The maximum number of allowed proposals by category
163          */
164         public final static int MAX_PROPOSALS = 200;
165
166         public final static String PHP_NATURE_ID = PLUGIN_ID + ".phpnature";
167
168         // Constants ---------------------------------------------------------------
169
170         public static final String ICON_OVERLAY_ERROR = "full/ovr16/error_co.gif"; //$NON-NLS-1$
171
172         public static final String ICON_OVERLAY_WARNING = "full/ovr16/warning_co.gif"; //$NON-NLS-1$
173
174         // Instance Variables ------------------------------------------------------
175
176         /** The shared instance. */
177         private static WebUI plugin;
178         
179         /**
180          * The combined preference store.
181          * 
182          * @since 3.0
183          */
184         private IPreferenceStore fCombinedPreferenceStore;
185
186         /**
187          * The coded template store for the java editor.
188          * 
189          * @since 3.0
190          */
191         private TemplateStore fCodeTemplateStore;
192
193         /**
194          * The code template context type registry for the java editor.
195          * 
196          * @since 3.0
197          */
198         private ContextTypeRegistry fCodeTemplateContextTypeRegistry;
199
200         /**
201          * The template context type registry for the java editor.
202          * 
203          * @since 3.0
204          */
205         private ContextTypeRegistry fContextTypeRegistry;
206
207         private ResourceAdapterFactory fResourceAdapterFactory;
208
209         private JavaElementAdapterFactory fJavaElementAdapterFactory;
210         
211         private ICompilationUnitDocumentProvider fCompilationUnitDocumentProvider;
212         
213         private JavaTextTools fJavaTextTools;
214
215         private IWorkingCopyManager fWorkingCopyManager;
216         
217         private IPropertyChangeListener fFontPropertyChangeListener;
218         
219         private ProblemMarkerManager fProblemMarkerManager;
220
221         private MockupPreferenceStore fMockupPreferenceStore;
222
223         private ImageDescriptorRegistry fImageDescriptorRegistry;
224         
225         private JavaEditorTextHoverDescriptor[] fJavaEditorTextHoverDescriptors;
226
227         private MembersOrderPreferenceCache fMembersOrderPreferenceCache;
228
229         private HashMap fIndexManagerMap = new HashMap();
230
231         /**
232          * The extension point registry for the
233          * <code>net.sourceforge.phpdt.ui.javaFoldingStructureProvider</code>
234          * extension point.
235          * 
236          * @since 3.0
237          */
238         private JavaFoldingStructureProviderRegistry fFoldingStructureProviderRegistry;
239
240         public static IWorkbenchPage getActivePage() {
241                 return getDefault().internalGetActivePage();
242         }
243
244         private IWorkbenchPage internalGetActivePage() {
245                 return getWorkbench().getActiveWorkbenchWindow().getActivePage();
246         }
247
248         public static Shell getActiveWorkbenchShell() {
249                 return getActiveWorkbenchWindow().getShell();
250         }
251
252         public static IWorkbenchWindow getActiveWorkbenchWindow() {
253                 return getDefault().getWorkbench().getActiveWorkbenchWindow();
254         }
255
256         // Public Methods ----------------------------------------------------------
257
258         /**
259          * Returns the shared instance.
260          */
261         public static WebUI getDefault() {
262                 return plugin;
263         }
264
265         /**
266          * Returns the workspace instance.
267          */
268         public static IWorkspace getWorkspace() {
269                 return ResourcesPlugin.getWorkspace();
270         }
271
272         /** The context type registry. */
273         private ContributionContextTypeRegistry fRegistry;
274
275         /** The template store. */
276         private TemplateStore fStore;
277
278         // Constructors ------------------------------------------------------------
279
280         /**
281          * The constructor.
282          */
283         public WebUI() {
284                 plugin = this;
285         }
286
287         /**
288          * Returns this plug-in's context type registry.
289          * 
290          * @return the context type registry for this plug-in instance
291          */
292         public ContextTypeRegistry getContextTypeRegistry() {
293                 if (fRegistry == null) {
294                         // create an configure the contexts available in the editor
295                         fRegistry = new ContributionContextTypeRegistry();
296                         fRegistry.addContextType(XMLTemplateContextType.XML_CONTEXT_TYPE);
297                         fRegistry.addContextType(HTMLTemplateContextType.HTML_CONTEXT_TYPE);
298                         fRegistry.addContextType(SmartyTemplateContextType.SMARTY_CONTEXT_TYPE);
299                         fRegistry.addContextType(JSTemplateContextType.JS_CONTEXT_TYPE);
300                 }
301                 return fRegistry;
302         }
303
304         // Private Methods ---------------------------------------------------------
305
306         /**
307          * Returns an image descriptor for the image corresponding to the specified
308          * key (which is the name of the image file).
309          * 
310          * @param key
311          *            The key of the image
312          * @return The descriptor for the requested image, or <code>null</code> if
313          *         the image could not be found
314          */
315         private ImageDescriptor getImageDescriptor(String key) {
316                 try {
317                         URL url = getBundle().getEntry("/icons/" + key); //$NON-NLS-1$
318                         return ImageDescriptor.createFromURL(url);
319                 } catch (IllegalStateException e) {
320                         return null;
321                 }
322         }
323
324         /**
325          * Returns this plug-in's template store.
326          * 
327          * @return the template store of this plug-in instance
328          */
329         public TemplateStore getTemplateStore() {
330                 if (fStore == null) {
331                         fStore = new ContributionTemplateStore(/*getContextTypeRegistry()*/getTemplateContextRegistry(),
332                                         getDefault().getPreferenceStore(), /*CUSTOM_*/TEMPLATES_KEY);
333                         try {
334                                 fStore.load();
335                         } catch (IOException e) {
336                                 WebUI
337                                                 .getDefault()
338                                                 .getLog()
339                                                 .log(
340                                                                 new Status(
341                                                                                 IStatus.ERROR,
342                                                                                 "net.sourceforge.phpeclipse.ui", IStatus.OK, "", e)); //$NON-NLS-1$ //$NON-NLS-2$
343                         }
344                 }
345                 return fStore;
346         }
347
348         /*
349          * @see AbstractUIPlugin#initializeImageRegistry(ImageRegistry)
350          */
351         protected void initializeImageRegistry(ImageRegistry reg) {
352                 reg.put(ICON_OVERLAY_ERROR, getImageDescriptor(ICON_OVERLAY_ERROR));
353                 reg.put(ICON_OVERLAY_WARNING, getImageDescriptor(ICON_OVERLAY_WARNING));
354         }
355
356         // private IWorkbenchPage internalGetActivePage() {
357         // IWorkbenchWindow window = getWorkbench().getActiveWorkbenchWindow();
358         // if (window != null)
359         // return window.getActivePage();
360         // return null;
361         // }
362
363         public static void log(IStatus status) {
364                 getDefault().getLog().log(status);
365         }
366
367         public static void log(Throwable e) {
368                 log(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.ERROR, ""
369                                 + e.getLocalizedMessage(), e));
370         }
371         
372         public static String getPluginId() {
373                 return getDefault().getBundle().getSymbolicName();
374         }
375         
376         /**
377          * Returns a combined preference store, this store is read-only.
378          * 
379          * @return the combined preference store
380          * 
381          * @since 3.0
382          */
383         public IPreferenceStore getCombinedPreferenceStore() {
384                 if (fCombinedPreferenceStore == null) {
385                         IPreferenceStore generalTextStore = EditorsUI.getPreferenceStore();
386                         fCombinedPreferenceStore = new ChainedPreferenceStore(
387                                         new IPreferenceStore[] {
388                                                         getPreferenceStore(),
389                                                         new PreferencesAdapter(WebUI
390                                                                         .getDefault().getPluginPreferences()),
391                                                         generalTextStore });
392                 }
393                 return fCombinedPreferenceStore;
394         }
395         
396         // TODO: refactor this into a better method name !
397         public synchronized ICompilationUnitDocumentProvider getCompilationUnitDocumentProvider() {
398                 if (fCompilationUnitDocumentProvider == null)
399                         fCompilationUnitDocumentProvider = new PHPDocumentProvider();
400                 return fCompilationUnitDocumentProvider;
401         }
402         
403         public synchronized JavaTextTools getJavaTextTools() {
404                 if (fJavaTextTools == null)
405                         fJavaTextTools = new JavaTextTools(getPreferenceStore(), /*JavaCore
406                                         .getPlugin().*/getPluginPreferences());
407                 return fJavaTextTools;
408         }
409         
410         public synchronized IWorkingCopyManager getWorkingCopyManager() {
411                 if (fWorkingCopyManager == null) {
412                         ICompilationUnitDocumentProvider provider = getCompilationUnitDocumentProvider();
413                         fWorkingCopyManager = new WorkingCopyManager(provider);
414                 }
415                 return fWorkingCopyManager;
416         }
417
418         public synchronized ProblemMarkerManager getProblemMarkerManager() {
419                 if (fProblemMarkerManager == null)
420                         fProblemMarkerManager = new ProblemMarkerManager();
421                 return fProblemMarkerManager;
422         }       
423
424         /**
425          * Returns the mockup preference store for firing events and registering
426          * listeners on project setting changes. Temporary solution.
427          */
428         public MockupPreferenceStore getMockupPreferenceStore() {
429                 if (fMockupPreferenceStore == null)
430                         fMockupPreferenceStore = new MockupPreferenceStore();
431
432                 return fMockupPreferenceStore;
433         }
434
435         public static ImageDescriptorRegistry getImageDescriptorRegistry() {
436                 return getDefault().internalGetImageDescriptorRegistry();
437         }
438         
439         private ImageDescriptorRegistry internalGetImageDescriptorRegistry() {
440                 if (fImageDescriptorRegistry == null)
441                         fImageDescriptorRegistry = new ImageDescriptorRegistry();
442                 return fImageDescriptorRegistry;
443         }
444         
445         /**
446          * Returns the registry of the extensions to the
447          * <code>net.sourceforge.phpdt.ui.javaFoldingStructureProvider</code>
448          * extension point.
449          * 
450          * @return the registry of contributed
451          *         <code>IJavaFoldingStructureProvider</code>
452          * @since 3.0
453          */
454         public synchronized JavaFoldingStructureProviderRegistry getFoldingStructureProviderRegistry() {
455                 if (fFoldingStructureProviderRegistry == null)
456                         fFoldingStructureProviderRegistry = new JavaFoldingStructureProviderRegistry();
457                 return fFoldingStructureProviderRegistry;
458         }       
459         /**
460          * Returns all Java editor text hovers contributed to the workbench.
461          * 
462          * @return an array of JavaEditorTextHoverDescriptor
463          * @since 2.1
464          */
465         public JavaEditorTextHoverDescriptor[] getJavaEditorTextHoverDescriptors() {
466                 if (fJavaEditorTextHoverDescriptors == null) {
467                         fJavaEditorTextHoverDescriptors = JavaEditorTextHoverDescriptor
468                                         .getContributedHovers();
469                         ConfigurationElementSorter sorter = new ConfigurationElementSorter() {
470                                 /*
471                                  * @see org.eclipse.ui.texteditor.ConfigurationElementSorter#getConfigurationElement(java.lang.Object)
472                                  */
473                                 public IConfigurationElement getConfigurationElement(
474                                                 Object object) {
475                                         return ((JavaEditorTextHoverDescriptor) object)
476                                                         .getConfigurationElement();
477                                 }
478                         };
479                         sorter.sort(fJavaEditorTextHoverDescriptors);
480
481                         // The Problem hover has to be the first and the Annotation hover
482                         // has to
483                         // be the last one in the JDT UI's hover list
484                         int length = fJavaEditorTextHoverDescriptors.length;
485                         int first = -1;
486                         int last = length - 1;
487                         int problemHoverIndex = -1;
488                         int annotationHoverIndex = -1;
489                         for (int i = 0; i < length; i++) {
490                                 if (!fJavaEditorTextHoverDescriptors[i].getId().startsWith(
491                                                 PLUGIN_ID)) {
492                                         if (problemHoverIndex == -1 || annotationHoverIndex == -1)
493                                                 continue;
494                                         else {
495                                                 last = i - 1;
496                                                 break;
497                                         }
498                                 }
499                                 if (first == -1)
500                                         first = i;
501
502                                 if (fJavaEditorTextHoverDescriptors[i].getId().equals(
503                                                 "net.sourceforge.phpdt.ui.AnnotationHover")) { //$NON-NLS-1$
504                                         annotationHoverIndex = i;
505                                         continue;
506                                 }
507                                 if (fJavaEditorTextHoverDescriptors[i].getId().equals(
508                                                 "net.sourceforge.phpdt.ui.ProblemHover")) { //$NON-NLS-1$
509                                         problemHoverIndex = i;
510                                         continue;
511                                 }
512                         }
513
514                         JavaEditorTextHoverDescriptor hoverDescriptor = null;
515
516                         if (first > -1 && problemHoverIndex > -1
517                                         && problemHoverIndex != first) {
518                                 // move problem hover to beginning
519                                 hoverDescriptor = fJavaEditorTextHoverDescriptors[first];
520                                 fJavaEditorTextHoverDescriptors[first] = fJavaEditorTextHoverDescriptors[problemHoverIndex];
521                                 fJavaEditorTextHoverDescriptors[problemHoverIndex] = hoverDescriptor;
522
523                                 // update annotation hover index if needed
524                                 if (annotationHoverIndex == first)
525                                         annotationHoverIndex = problemHoverIndex;
526                         }
527
528                         if (annotationHoverIndex > -1 && annotationHoverIndex != last) {
529                                 // move annotation hover to end
530                                 hoverDescriptor = fJavaEditorTextHoverDescriptors[last];
531                                 fJavaEditorTextHoverDescriptors[last] = fJavaEditorTextHoverDescriptors[annotationHoverIndex];
532                                 fJavaEditorTextHoverDescriptors[annotationHoverIndex] = hoverDescriptor;
533                         }
534
535                         // Move Best Match hover to front
536                         for (int i = 0; i < fJavaEditorTextHoverDescriptors.length - 1; i++) {
537                                 if (PreferenceConstants.ID_BESTMATCH_HOVER
538                                                 .equals(fJavaEditorTextHoverDescriptors[i].getId())) {
539                                         hoverDescriptor = fJavaEditorTextHoverDescriptors[i];
540                                         for (int j = i; j > 0; j--)
541                                                 fJavaEditorTextHoverDescriptors[j] = fJavaEditorTextHoverDescriptors[j - 1];
542                                         fJavaEditorTextHoverDescriptors[0] = hoverDescriptor;
543                                         break;
544                                 }
545
546                         }
547                 }
548
549                 return fJavaEditorTextHoverDescriptors;
550         }
551
552         public synchronized MembersOrderPreferenceCache getMemberOrderPreferenceCache() {
553                 if (fMembersOrderPreferenceCache == null)
554                         fMembersOrderPreferenceCache = new MembersOrderPreferenceCache();
555                 return fMembersOrderPreferenceCache;
556         }
557         /**
558          * Open a file in the Workbench that may or may not exist in the workspace.
559          * Must be run on the UI thread.
560          * 
561          * @param filename
562          * @throws CoreException
563          */
564         public ITextEditor openFileInTextEditor(String filename)
565                         throws CoreException {
566                 // reject directories
567                 if (new File(filename).isDirectory())
568                         return null;
569                 IWorkbench workbench = PlatformUI.getWorkbench();
570                 IWorkbenchWindow window = workbench.getWorkbenchWindows()[0];
571                 IWorkbenchPage page = window.getActivePage();
572                 IPath path = new Path(filename);
573                 // If the file exists in the workspace, open it
574                 IFile file = getWorkspace().getRoot().getFile(path);
575                 IEditorPart editor;
576                 ITextEditor textEditor;
577                 if (file != null && file.exists()) {
578                         editor = IDE.openEditor(page, file, true);
579                         textEditor = (ITextEditor) editor.getAdapter(ITextEditor.class);
580                 } else {
581                         // Otherwise open the stream directly
582                         if (page == null)
583                                 return null;
584                         FileStorage storage = new FileStorage(path);
585                         IEditorRegistry registry = getWorkbench().getEditorRegistry();
586                         IEditorDescriptor desc = registry.getDefaultEditor(filename);
587                         if (desc == null) {
588                                 desc = registry
589                                                 .findEditor(IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID);
590                                 // desc = registry.getDefaultEditor();
591                         }
592                         IEditorInput input = new ExternalEditorInput(storage);
593                         editor = page.openEditor(input, desc.getId());
594                         textEditor = (ITextEditor) editor.getAdapter(ITextEditor.class);
595                         // If the storage provider is not ours, we can't guarantee
596                         // read/write.
597                         if (textEditor != null) {
598                                 IDocumentProvider documentProvider = textEditor
599                                                 .getDocumentProvider();
600                                 if (!(documentProvider instanceof ExternalStorageDocumentProvider)) {
601                                         storage.setReadOnly();
602                                 }
603                         }
604                 }
605                 return textEditor;
606         }
607         /**
608          * Creates the PHP plugin standard groups in a context menu.
609          */
610         public static void createStandardGroups(IMenuManager menu) {
611                 if (!menu.isEmpty())
612                         return;
613                 menu.add(new Separator(IContextMenuConstants.GROUP_NEW));
614                 menu.add(new GroupMarker(IContextMenuConstants.GROUP_GOTO));
615                 menu.add(new Separator(IContextMenuConstants.GROUP_OPEN));
616                 menu.add(new GroupMarker(IContextMenuConstants.GROUP_SHOW));
617                 menu.add(new Separator(IContextMenuConstants.GROUP_REORGANIZE));
618                 menu.add(new Separator(IContextMenuConstants.GROUP_GENERATE));
619                 menu.add(new Separator(IContextMenuConstants.GROUP_SEARCH));
620                 menu.add(new Separator(IContextMenuConstants.GROUP_BUILD));
621                 menu.add(new Separator(IContextMenuConstants.GROUP_ADDITIONS));
622                 menu.add(new Separator(IContextMenuConstants.GROUP_VIEWER_SETUP));
623                 menu.add(new Separator(IContextMenuConstants.GROUP_PROPERTIES));
624         }
625
626         public IdentifierIndexManager getIndexManager(IProject iProject) {
627                 IPath path = iProject.getWorkingLocation(/*WebUI*/PHPeclipsePlugin.PLUGIN_ID);
628                 path = path.append("project.index");
629                 String indexFilename = path.toString();
630                 // try {
631                 // IdentDB db = IdentDB.getInstance();
632                 // } catch (ClassNotFoundException e) {
633                 // e.printStackTrace();
634                 // } catch (SQLException e) {
635                 // e.printStackTrace();
636                 // }
637                 IdentifierIndexManager indexManager = (IdentifierIndexManager) fIndexManagerMap
638                                 .get(indexFilename);
639                 if (indexManager == null) {
640                         indexManager = new IdentifierIndexManager(indexFilename);
641                         fIndexManagerMap.put(indexFilename, indexManager);
642                 }
643                 return indexManager;
644         }
645
646         /**
647          * Returns the template store for the code generation templates.
648          * 
649          * @return the template store for the code generation templates
650          * @since 3.0
651          */
652         public TemplateStore getCodeTemplateStore() {
653                 if (fCodeTemplateStore == null) {
654                         fCodeTemplateStore = new ContributionTemplateStore(
655                                         getCodeTemplateContextRegistry(), getPreferenceStore(),
656                                         CODE_TEMPLATES_KEY);
657                         try {
658                                 fCodeTemplateStore.load();
659                         } catch (IOException e) {
660                                 log(e);
661                         }
662                 }
663
664                 return fCodeTemplateStore;
665         }
666         /**
667          * Returns the template context type registry for the code generation
668          * templates.
669          * 
670          * @return the template context type registry for the code generation
671          *         templates
672          * @since 3.0
673          */
674         public ContextTypeRegistry getCodeTemplateContextRegistry() {
675                 if (fCodeTemplateContextTypeRegistry == null) {
676                         fCodeTemplateContextTypeRegistry = new ContributionContextTypeRegistry();
677
678                         CodeTemplateContextType
679                                         .registerContextTypes(fCodeTemplateContextTypeRegistry);
680                 }
681
682                 return fCodeTemplateContextTypeRegistry;
683         }
684
685         public void openFileAndGotoOffset(String filename, int offset, int length)
686         throws CoreException {
687                 ITextEditor textEditor = openFileInTextEditor(filename);
688                 if (textEditor != null) {
689                         // If a line number was given, go to it
690                         if (offset >= 0) {
691 //                              IDocument document = textEditor.getDocumentProvider()
692 //                                              .getDocument(textEditor.getEditorInput());
693                                 textEditor.selectAndReveal(offset, length);
694                         }
695                 }
696         }
697
698         public void openFileAndFindString(String filename, String findString)
699         throws CoreException {
700                 ITextEditor textEditor = openFileInTextEditor(filename);
701                 if (textEditor != null) {
702                         // If a string was given, go to it
703                         if (findString != null) {
704                                 try {
705                                         IDocument document = textEditor.getDocumentProvider()
706                                                         .getDocument(textEditor.getEditorInput());
707                                         int offset = document.search(0, findString, true, false,
708                                                         true);
709                                         textEditor.selectAndReveal(offset, findString.length());
710                                 } catch (BadLocationException e) {
711                                         // invalid text position -> do nothing
712                                 }
713                         }
714                 }
715         }
716
717          public static void logErrorMessage(String message) {
718                  log(new Status(IStatus.ERROR, getPluginId(),IJavaStatusConstants.INTERNAL_ERROR, message, null));
719          }
720                 public static void log(int severity, String message) {
721                         Status status = new Status(severity, PLUGIN_ID, IStatus.OK, message,
722                                         null);
723                         log(status);
724                 }
725
726                 public static void log(String message, Throwable t) {
727                         log(error(message, t));
728                 }
729                 public static IStatus error(Throwable t) {
730                         return error("PHPeclipsePlugin.internalErrorOccurred", t); //$NON-NLS-1$
731                 }
732
733                 public static IStatus error(String message, Throwable t) {
734                         return new Status(IStatus.ERROR, PLUGIN_ID, IStatus.ERROR, message, t);
735                 }
736
737                 /**
738                  * Resets the Java editor text hovers contributed to the workbench.
739                  * <p>
740                  * This will force a rebuild of the descriptors the next time a client asks
741                  * for them.
742                  * </p>
743                  * 
744                  * @return an array of JavaEditorTextHoverDescriptor
745                  * @since 2.1
746                  */
747                 public void resetJavaEditorTextHoverDescriptors() {
748                         fJavaEditorTextHoverDescriptors = null;
749                 }
750
751                 /**
752                  * Returns the template context type registry for the java plugin.
753                  * 
754                  * @return the template context type registry for the java plugin
755                  * @since 3.0
756                  */
757                 public ContextTypeRegistry getTemplateContextRegistry() {
758                         if (fContextTypeRegistry == null) {
759                                 fContextTypeRegistry = new ContributionContextTypeRegistry();
760         
761                                 fContextTypeRegistry.addContextType(new JavaContextType());
762                                 fContextTypeRegistry.addContextType(new JavaDocContextType());
763                                 fContextTypeRegistry.addContextType(new HTMLContextType());
764                         }
765         
766                         return fContextTypeRegistry;
767                 }
768                 // public static void logErrorMessage(String message) {
769                 // log(new Status(IStatus.ERROR, getPluginId(),
770                 // JavaStatusConstants.INTERNAL_ERROR, message, null));
771                 // }
772
773
774
775                 /*
776                  * (non - Javadoc) Method declared in Plugin
777                  */
778                 public void start(BundleContext context) throws Exception {
779                         super.start(context);
780         
781                         // JavaCore.start(this, context);
782                         final JavaModelManager modelManager = JavaModelManager
783                                         .getJavaModelManager();
784                         try {
785                                 modelManager.configurePluginDebugOptions();
786         
787                                 // request state folder creation (workaround 19885)
788                                 getStateLocation();
789                                 // retrieve variable values
790                                 PHPeclipsePlugin.getDefault().getPluginPreferences()
791                                                 .addPropertyChangeListener(
792                                                                 new JavaModelManager.PluginPreferencesListener());
793                                 // manager.loadVariablesAndContainers();
794         
795                                 final IWorkspace workspace = ResourcesPlugin.getWorkspace();
796                                 workspace.addResourceChangeListener(modelManager.deltaState,
797                                                 IResourceChangeEvent.PRE_BUILD
798                                                                 | IResourceChangeEvent.POST_BUILD
799                                                                 | IResourceChangeEvent.POST_CHANGE
800                                                                 | IResourceChangeEvent.PRE_DELETE
801                                                                 | IResourceChangeEvent.PRE_CLOSE);
802         
803                                 ISavedState savedState = workspace.addSaveParticipant(
804                                                 /*PHPeclipsePlugin*/WebUI.this, modelManager);
805         
806                                 WorkspaceJob processSavedState = new WorkspaceJob(
807                                                 Util.bind("savedState.jobName")) { //$NON-NLS-1$
808                                         public IStatus runInWorkspace(IProgressMonitor monitor)
809                                                         throws CoreException {
810                                                 ISavedState savedState = workspace.addSaveParticipant(
811                                                                 /*PHPeclipsePlugin*/WebUI.this, modelManager);
812                                                 if (savedState != null) {
813                                                         modelManager.deltaState.getDeltaProcessor().overridenEventType
814                                                                         = IResourceChangeEvent.POST_CHANGE;
815                                                         savedState.processResourceChangeEvents(modelManager.deltaState);
816                                                 }
817                                                 return Status.OK_STATUS;
818                                         }
819                                 };
820                                 processSavedState.setSystem(true);
821                                 processSavedState.setPriority(Job.SHORT); // process asap
822                                 processSavedState.schedule();
823                         } catch (RuntimeException e) {
824                                 modelManager.shutdown();
825                                 throw e;
826                         }
827         
828                         registerAdapters();
829         
830                         // if (USE_WORKING_COPY_OWNERS) {
831                         WorkingCopyOwner.setPrimaryBufferProvider(new WorkingCopyOwner() {
832                                 public IBuffer createBuffer(ICompilationUnit workingCopy) {
833                                         ICompilationUnit original = workingCopy.getPrimary();
834                                         IResource resource = original.getResource();
835                                         if (resource instanceof IFile)
836                                                 return new DocumentAdapter(workingCopy, (IFile) resource);
837                                         return DocumentAdapter.NULL;
838                                 }
839                         });
840                         // }
841         
842                         installPreferenceStoreBackwardsCompatibility();
843         
844                 }
845         
846
847                 private void registerAdapters() {
848                 fJavaElementAdapterFactory = new JavaElementAdapterFactory();
849                 fResourceAdapterFactory = new ResourceAdapterFactory();
850
851                 IAdapterManager manager = Platform.getAdapterManager();
852                 manager
853                                 .registerAdapters(fJavaElementAdapterFactory,
854                                                 IJavaElement.class);
855                 manager.registerAdapters(fResourceAdapterFactory, IResource.class);
856         }
857
858
859
860                 /**
861                  * Installs backwards compatibility for the preference store.
862                  */
863                 private void installPreferenceStoreBackwardsCompatibility() {
864         
865                         /*
866                          * Installs backwards compatibility: propagate the Java editor font from
867                          * a pre-2.1 plug-in to the Platform UI's preference store to preserve
868                          * the Java editor font from a pre-2.1 workspace. This is done only
869                          * once.
870                          */
871                         String fontPropagatedKey = "fontPropagated"; //$NON-NLS-1$
872                         if (getPreferenceStore().contains(JFaceResources.TEXT_FONT)
873                                         && !getPreferenceStore().isDefault(JFaceResources.TEXT_FONT)) {
874                                 if (!getPreferenceStore().getBoolean(fontPropagatedKey))
875                                         PreferenceConverter
876                                                         .setValue(PlatformUI.getWorkbench()
877                                                                         .getPreferenceStore(),
878                                                                         PreferenceConstants.EDITOR_TEXT_FONT,
879                                                                         PreferenceConverter.getFontDataArray(
880                                                                                         getPreferenceStore(),
881                                                                                         JFaceResources.TEXT_FONT));
882                         }
883                         getPreferenceStore().setValue(fontPropagatedKey, true);
884         
885                         /*
886                          * Backwards compatibility: set the Java editor font in this plug-in's
887                          * preference store to let older versions access it. Since 2.1 the Java
888                          * editor font is managed by the workbench font preference page.
889                          */
890                         PreferenceConverter.putValue(getPreferenceStore(),
891                                         JFaceResources.TEXT_FONT, JFaceResources.getFontRegistry()
892                                                         .getFontData(PreferenceConstants.EDITOR_TEXT_FONT));
893         
894                         fFontPropertyChangeListener = new IPropertyChangeListener() {
895                                 public void propertyChange(PropertyChangeEvent event) {
896                                         if (PreferenceConstants.EDITOR_TEXT_FONT.equals(event
897                                                         .getProperty()))
898                                                 PreferenceConverter.putValue(getPreferenceStore(),
899                                                                 JFaceResources.TEXT_FONT,
900                                                                 JFaceResources.getFontRegistry().getFontData(
901                                                                                 PreferenceConstants.EDITOR_TEXT_FONT));
902                                 }
903                         };
904                         // incastrix
905                         /*JFaceResources.getFontRegistry().addListener(
906                                         fFontPropertyChangeListener);*/
907                 }
908                 
909
910 }