Common tests utilities adn decorators.
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / PHPeclipsePlugin.java
1 /**********************************************************************
2  Copyright (c) 2000, 2002 IBM Corp. 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  **********************************************************************/
9 package net.sourceforge.phpeclipse;
10
11 import java.io.File;
12 import java.io.IOException;
13 import java.io.InputStream;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.Enumeration;
17 import java.util.HashMap;
18 import java.util.HashSet;
19 import java.util.Iterator;
20 import java.util.List;
21 import java.util.PropertyResourceBundle;
22 import java.util.Set;
23
24 import net.sourceforge.phpdt.core.IBuffer;
25 import net.sourceforge.phpdt.core.IBufferFactory;
26 import net.sourceforge.phpdt.core.ICompilationUnit;
27 import net.sourceforge.phpdt.core.IJavaElement;
28 import net.sourceforge.phpdt.core.JavaCore;
29 import net.sourceforge.phpdt.core.WorkingCopyOwner;
30 import net.sourceforge.phpdt.internal.core.BatchOperation;
31 import net.sourceforge.phpdt.internal.core.JavaModelManager;
32 import net.sourceforge.phpdt.internal.core.util.Util;
33 import net.sourceforge.phpdt.internal.corext.template.php.CodeTemplateContextType;
34 import net.sourceforge.phpdt.internal.corext.template.php.HTMLContextType;
35 import net.sourceforge.phpdt.internal.corext.template.php.JavaContextType;
36 import net.sourceforge.phpdt.internal.corext.template.php.JavaDocContextType;
37 import net.sourceforge.phpdt.internal.ui.IJavaStatusConstants;
38 import net.sourceforge.phpdt.internal.ui.JavaElementAdapterFactory;
39 import net.sourceforge.phpdt.internal.ui.ResourceAdapterFactory;
40 import net.sourceforge.phpdt.internal.ui.preferences.MembersOrderPreferenceCache;
41 import net.sourceforge.phpdt.internal.ui.preferences.MockupPreferenceStore;
42 import net.sourceforge.phpdt.internal.ui.text.PreferencesAdapter;
43 import net.sourceforge.phpdt.internal.ui.text.folding.JavaFoldingStructureProviderRegistry;
44 import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaEditorTextHoverDescriptor;
45 import net.sourceforge.phpdt.internal.ui.viewsupport.ImageDescriptorRegistry;
46 import net.sourceforge.phpdt.internal.ui.viewsupport.ProblemMarkerManager;
47 import net.sourceforge.phpdt.ui.IContextMenuConstants;
48 import net.sourceforge.phpdt.ui.IWorkingCopyManager;
49 import net.sourceforge.phpdt.ui.PreferenceConstants;
50 import net.sourceforge.phpdt.ui.text.JavaTextTools;
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.phpeditor.CustomBufferFactory;
56 import net.sourceforge.phpeclipse.phpeditor.DocumentAdapter;
57 import net.sourceforge.phpeclipse.phpeditor.ICompilationUnitDocumentProvider;
58 import net.sourceforge.phpeclipse.phpeditor.PHPDocumentProvider;
59 import net.sourceforge.phpeclipse.phpeditor.PHPSyntaxRdr;
60 import net.sourceforge.phpeclipse.phpeditor.WorkingCopyManager;
61 import net.sourceforge.phpeclipse.phpeditor.util.PHPColorProvider;
62
63 import org.eclipse.core.resources.IFile;
64 import org.eclipse.core.resources.IProject;
65 import org.eclipse.core.resources.IResource;
66 import org.eclipse.core.resources.IResourceChangeEvent;
67 import org.eclipse.core.resources.ISavedState;
68 import org.eclipse.core.resources.IWorkspace;
69 import org.eclipse.core.resources.IWorkspaceRunnable;
70 import org.eclipse.core.resources.ResourcesPlugin;
71 import org.eclipse.core.runtime.CoreException;
72 import org.eclipse.core.runtime.IAdapterManager;
73 import org.eclipse.core.runtime.IConfigurationElement;
74 import org.eclipse.core.runtime.IPath;
75 import org.eclipse.core.runtime.IProgressMonitor;
76 import org.eclipse.core.runtime.IStatus;
77 import org.eclipse.core.runtime.Path;
78 import org.eclipse.core.runtime.Platform;
79 import org.eclipse.core.runtime.Status;
80 import org.eclipse.core.runtime.jobs.ISchedulingRule;
81 import org.eclipse.core.runtime.jobs.Job;
82 import org.eclipse.jface.action.GroupMarker;
83 import org.eclipse.jface.action.IMenuManager;
84 import org.eclipse.jface.action.Separator;
85 import org.eclipse.jface.preference.IPreferenceStore;
86 import org.eclipse.jface.preference.PreferenceConverter;
87 import org.eclipse.jface.resource.JFaceResources;
88 import org.eclipse.jface.text.BadLocationException;
89 import org.eclipse.jface.text.IDocument;
90 import org.eclipse.jface.text.templates.ContextTypeRegistry;
91 import org.eclipse.jface.text.templates.persistence.TemplateStore;
92 import org.eclipse.jface.util.IPropertyChangeListener;
93 import org.eclipse.jface.util.PropertyChangeEvent;
94 import org.eclipse.swt.graphics.RGB;
95 import org.eclipse.swt.widgets.Display;
96 import org.eclipse.swt.widgets.Shell;
97 import org.eclipse.ui.IEditorDescriptor;
98 import org.eclipse.ui.IEditorInput;
99 import org.eclipse.ui.IEditorPart;
100 import org.eclipse.ui.IEditorRegistry;
101 import org.eclipse.ui.IWorkbench;
102 import org.eclipse.ui.IWorkbenchPage;
103 import org.eclipse.ui.IWorkbenchWindow;
104 import org.eclipse.ui.PlatformUI;
105 import org.eclipse.ui.editors.text.EditorsUI;
106 import org.eclipse.ui.editors.text.templates.ContributionContextTypeRegistry;
107 import org.eclipse.ui.editors.text.templates.ContributionTemplateStore;
108 import org.eclipse.ui.ide.IDE;
109 import org.eclipse.ui.plugin.AbstractUIPlugin;
110 import org.eclipse.ui.texteditor.ChainedPreferenceStore;
111 import org.eclipse.ui.texteditor.ConfigurationElementSorter;
112 import org.eclipse.ui.texteditor.IDocumentProvider;
113 import org.eclipse.ui.texteditor.ITextEditor;
114 import org.eclipse.ui.texteditor.MarkerAnnotationPreferences;
115 import org.osgi.framework.BundleContext;
116
117 /**
118  * The main plugin class to be used in the desktop.
119  */
120 public class PHPeclipsePlugin extends AbstractUIPlugin implements
121                 IPreferenceConstants {
122         /**
123          * The id of the PHP plugin (value <code>"net.sourceforge.phpeclipse"</code>).
124          */
125         public static final String PLUGIN_ID = "net.sourceforge.phpeclipse"; //$NON-NLS-1$
126
127         public static final String EDITOR_ID = PHPeclipsePlugin.PLUGIN_ID
128                         + ".PHPUnitEditor";
129
130         public static final String ID_PERSPECTIVE = "net.sourceforge.phpeclipse.PHPPerspective"; //$NON-NLS-1$
131
132         IWorkspace w;
133
134         /**
135          * id of builder - matches plugin.xml (concatenate pluginid.builderid)
136          */
137         public static final String BUILDER_PARSER_ID = PLUGIN_ID + ".parserbuilder";
138
139         // public static final String BUILDER_INDEX_ID = PLUGIN_ID +
140         // ".indexbuilder";
141         /** General debug flag */
142
143         public static final boolean DEBUG = false;
144
145         /**
146          * The maximum number of allowed proposals by category
147          */
148         public final static int MAX_PROPOSALS = 200;
149
150         /**
151          * The key to store customized templates.
152          * 
153          * @since 3.0
154          */
155         private static final String TEMPLATES_KEY = "net.sourceforge.phpdt.ui.text.custom_templates"; //$NON-NLS-1$
156
157         /**
158          * The key to store customized code templates.
159          * 
160          * @since 3.0
161          */
162         private static final String CODE_TEMPLATES_KEY = "net.sourceforge.phpdt.ui.text.custom_code_templates"; //$NON-NLS-1$
163
164         /**
165          * The key to store whether the legacy templates have been migrated
166          * 
167          * @since 3.0
168          */
169         // private static final String TEMPLATES_MIGRATION_KEY=
170         // "net.sourceforge.phpdt.ui.text.templates_migrated"; //$NON-NLS-1$
171         /**
172          * The key to store whether the legacy code templates have been migrated
173          * 
174          * @since 3.0
175          */
176         // private static final String CODE_TEMPLATES_MIGRATION_KEY=
177         // "net.sourceforge.phpdt.ui.text.code_templates_migrated";
178         // //$NON-NLS-1$
179         // private static ExternalToolsPlugin externalTools;
180         /**
181          * The Java virtual machine that we are running on.
182          */
183         // private static int jvm;
184         // /** MRJ 2.0 */
185         // private static final int MRJ_2_0 = 0;
186         //
187         // /** MRJ 2.1 or later */
188         // private static final int MRJ_2_1 = 1;
189         //
190         // /** Java on Mac OS X 10.0 (MRJ 3.0) */
191         // private static final int MRJ_3_0 = 3;
192         //
193         // /** MRJ 3.1 */
194         // private static final int MRJ_3_1 = 4;
195         //
196         // /** JVM constant for any other platform */
197         // private static final int OTHER = -1;
198         // public static final String PHP_RESOURCES_VIEW_ID = PLUGIN_ID +
199         // ".resourcesview.ViewPHPResources"; //$NON-NLS-1$
200         public static final String PHP_CODING_ACTION_SET_ID = PLUGIN_ID
201                         + ".ui.CodingActionSet"; //$NON-NLS-1$
202
203         public final static String PHP_NATURE_ID = PLUGIN_ID + ".phpnature";
204
205         public static final String PHPPARSER_ORIGINAL = "net.sourceforge.phpdt.internal.compiler.parser.Parser";
206
207         public static final String PHPPARSER_NEW = "test.PHPParser";
208
209         /** Change this if you want to switch PHP Parser. */
210         public static final String PHPPARSER = PHPPARSER_ORIGINAL;
211
212         // The shared instance.
213         private static PHPeclipsePlugin plugin;
214
215         /**
216          * The template context type registry for the java editor.
217          * 
218          * @since 3.0
219          */
220         private ContextTypeRegistry fContextTypeRegistry;
221
222         /**
223          * The code template context type registry for the java editor.
224          * 
225          * @since 3.0
226          */
227         private ContextTypeRegistry fCodeTemplateContextTypeRegistry;
228
229         /**
230          * The template store for the java editor.
231          * 
232          * @since 3.0
233          */
234         private TemplateStore fTemplateStore;
235
236         /**
237          * The coded template store for the java editor.
238          * 
239          * @since 3.0
240          */
241         private TemplateStore fCodeTemplateStore;
242
243         /** Windows 9x */
244         private static final int WINDOWS_9x = 6;
245
246         /** Windows NT */
247         private static final int WINDOWS_NT = 5;
248
249         private ImageDescriptorRegistry fImageDescriptorRegistry;
250
251         private HashMap fIndexManagerMap = new HashMap();
252
253         private IWorkingCopyManager fWorkingCopyManager;
254
255         private IBufferFactory fBufferFactory;
256
257         private ICompilationUnitDocumentProvider fCompilationUnitDocumentProvider;
258
259         private JavaTextTools fJavaTextTools;
260
261         private ProblemMarkerManager fProblemMarkerManager;
262
263         private MembersOrderPreferenceCache fMembersOrderPreferenceCache;
264
265         private IFile fLastEditorFile = null;
266
267         private JavaEditorTextHoverDescriptor[] fJavaEditorTextHoverDescriptors;
268
269         private JavaElementAdapterFactory fJavaElementAdapterFactory;
270
271         // private MarkerAdapterFactory fMarkerAdapterFactory;
272         // private EditorInputAdapterFactory fEditorInputAdapterFactory;
273         private ResourceAdapterFactory fResourceAdapterFactory;
274
275         // private LogicalPackageAdapterFactory fLogicalPackageAdapterFactory;
276         private IPropertyChangeListener fFontPropertyChangeListener;
277
278         /**
279          * Property change listener on this plugin's preference store.
280          * 
281          * @since 3.0
282          */
283         // private IPropertyChangeListener fPropertyChangeListener;
284         /**
285          * The combined preference store.
286          * 
287          * @since 3.0
288          */
289         private IPreferenceStore fCombinedPreferenceStore;
290
291         /**
292          * The extension point registry for the
293          * <code>net.sourceforge.phpdt.ui.javaFoldingStructureProvider</code>
294          * extension point.
295          * 
296          * @since 3.0
297          */
298         private JavaFoldingStructureProviderRegistry fFoldingStructureProviderRegistry;
299
300         /**
301          * Mockup preference store for firing events and registering listeners on
302          * project setting changes. FIXME: Temporary solution.
303          * 
304          * @since 3.0
305          */
306         private MockupPreferenceStore fMockupPreferenceStore;
307
308         /**
309          * The constructor.
310          */
311         public PHPeclipsePlugin() {
312                 super();
313                 plugin = this;
314                 // externalTools = new ExternalToolsPlugin();
315
316                 // try {
317                 // resourceBundle =
318                 // ResourceBundle.getBundle("net.sourceforge.PHPeclipsePluginResources");
319                 // } catch (MissingResourceException x) {
320                 // resourceBundle = null;
321                 // }
322         }
323
324         // /**
325         // * Returns all Java editor text hovers contributed to the workbench.
326         // *
327         // * @return an array of JavaEditorTextHoverDescriptor
328         // * @since 2.1
329         // */
330         // public JavaEditorTextHoverDescriptor[]
331         // getJavaEditorTextHoverDescriptors()
332         // {
333         // if (fJavaEditorTextHoverDescriptors == null)
334         // fJavaEditorTextHoverDescriptors = JavaEditorTextHoverDescriptor
335         // .getContributedHovers();
336         // return fJavaEditorTextHoverDescriptors;
337         // }
338         /**
339          * Returns all Java editor text hovers contributed to the workbench.
340          * 
341          * @return an array of JavaEditorTextHoverDescriptor
342          * @since 2.1
343          */
344         public JavaEditorTextHoverDescriptor[] getJavaEditorTextHoverDescriptors() {
345                 if (fJavaEditorTextHoverDescriptors == null) {
346                         fJavaEditorTextHoverDescriptors = JavaEditorTextHoverDescriptor
347                                         .getContributedHovers();
348                         ConfigurationElementSorter sorter = new ConfigurationElementSorter() {
349                                 /*
350                                  * @see org.eclipse.ui.texteditor.ConfigurationElementSorter#getConfigurationElement(java.lang.Object)
351                                  */
352                                 public IConfigurationElement getConfigurationElement(
353                                                 Object object) {
354                                         return ((JavaEditorTextHoverDescriptor) object)
355                                                         .getConfigurationElement();
356                                 }
357                         };
358                         sorter.sort(fJavaEditorTextHoverDescriptors);
359
360                         // The Problem hover has to be the first and the Annotation hover
361                         // has to
362                         // be the last one in the JDT UI's hover list
363                         int length = fJavaEditorTextHoverDescriptors.length;
364                         int first = -1;
365                         int last = length - 1;
366                         int problemHoverIndex = -1;
367                         int annotationHoverIndex = -1;
368                         for (int i = 0; i < length; i++) {
369                                 if (!fJavaEditorTextHoverDescriptors[i].getId().startsWith(
370                                                 PLUGIN_ID)) {
371                                         if (problemHoverIndex == -1 || annotationHoverIndex == -1)
372                                                 continue;
373                                         else {
374                                                 last = i - 1;
375                                                 break;
376                                         }
377                                 }
378                                 if (first == -1)
379                                         first = i;
380
381                                 if (fJavaEditorTextHoverDescriptors[i].getId().equals(
382                                                 "net.sourceforge.phpdt.ui.AnnotationHover")) { //$NON-NLS-1$
383                                         annotationHoverIndex = i;
384                                         continue;
385                                 }
386                                 if (fJavaEditorTextHoverDescriptors[i].getId().equals(
387                                                 "net.sourceforge.phpdt.ui.ProblemHover")) { //$NON-NLS-1$
388                                         problemHoverIndex = i;
389                                         continue;
390                                 }
391                         }
392
393                         JavaEditorTextHoverDescriptor hoverDescriptor = null;
394
395                         if (first > -1 && problemHoverIndex > -1
396                                         && problemHoverIndex != first) {
397                                 // move problem hover to beginning
398                                 hoverDescriptor = fJavaEditorTextHoverDescriptors[first];
399                                 fJavaEditorTextHoverDescriptors[first] = fJavaEditorTextHoverDescriptors[problemHoverIndex];
400                                 fJavaEditorTextHoverDescriptors[problemHoverIndex] = hoverDescriptor;
401
402                                 // update annotation hover index if needed
403                                 if (annotationHoverIndex == first)
404                                         annotationHoverIndex = problemHoverIndex;
405                         }
406
407                         if (annotationHoverIndex > -1 && annotationHoverIndex != last) {
408                                 // move annotation hover to end
409                                 hoverDescriptor = fJavaEditorTextHoverDescriptors[last];
410                                 fJavaEditorTextHoverDescriptors[last] = fJavaEditorTextHoverDescriptors[annotationHoverIndex];
411                                 fJavaEditorTextHoverDescriptors[annotationHoverIndex] = hoverDescriptor;
412                         }
413
414                         // Move Best Match hover to front
415                         for (int i = 0; i < fJavaEditorTextHoverDescriptors.length - 1; i++) {
416                                 if (PreferenceConstants.ID_BESTMATCH_HOVER
417                                                 .equals(fJavaEditorTextHoverDescriptors[i].getId())) {
418                                         hoverDescriptor = fJavaEditorTextHoverDescriptors[i];
419                                         for (int j = i; j > 0; j--)
420                                                 fJavaEditorTextHoverDescriptors[j] = fJavaEditorTextHoverDescriptors[j - 1];
421                                         fJavaEditorTextHoverDescriptors[0] = hoverDescriptor;
422                                         break;
423                                 }
424
425                         }
426                 }
427
428                 return fJavaEditorTextHoverDescriptors;
429         }
430
431         /**
432          * Resets the Java editor text hovers contributed to the workbench.
433          * <p>
434          * This will force a rebuild of the descriptors the next time a client asks
435          * for them.
436          * </p>
437          * 
438          * @return an array of JavaEditorTextHoverDescriptor
439          * @since 2.1
440          */
441         public void resetJavaEditorTextHoverDescriptors() {
442                 fJavaEditorTextHoverDescriptors = null;
443         }
444
445         /**
446          * Creates the PHP plugin standard groups in a context menu.
447          */
448         public static void createStandardGroups(IMenuManager menu) {
449                 if (!menu.isEmpty())
450                         return;
451                 menu.add(new Separator(IContextMenuConstants.GROUP_NEW));
452                 menu.add(new GroupMarker(IContextMenuConstants.GROUP_GOTO));
453                 menu.add(new Separator(IContextMenuConstants.GROUP_OPEN));
454                 menu.add(new GroupMarker(IContextMenuConstants.GROUP_SHOW));
455                 menu.add(new Separator(IContextMenuConstants.GROUP_REORGANIZE));
456                 menu.add(new Separator(IContextMenuConstants.GROUP_GENERATE));
457                 menu.add(new Separator(IContextMenuConstants.GROUP_SEARCH));
458                 menu.add(new Separator(IContextMenuConstants.GROUP_BUILD));
459                 menu.add(new Separator(IContextMenuConstants.GROUP_ADDITIONS));
460                 menu.add(new Separator(IContextMenuConstants.GROUP_VIEWER_SETUP));
461                 menu.add(new Separator(IContextMenuConstants.GROUP_PROPERTIES));
462         }
463
464         public static IWorkbenchPage getActivePage() {
465                 return getDefault().internalGetActivePage();
466         }
467
468         public static Shell getActiveWorkbenchShell() {
469                 return getActiveWorkbenchWindow().getShell();
470         }
471
472         /**
473          * Returns an array of all editors that have an unsaved content. If the
474          * identical content is presented in more than one editor, only one of those
475          * editor parts is part of the result.
476          * 
477          * @return an array of all dirty editor parts.
478          */
479         public static IEditorPart[] getDirtyEditors() {
480                 Set inputs = new HashSet();
481                 List result = new ArrayList(0);
482                 IWorkbench workbench = getDefault().getWorkbench();
483                 IWorkbenchWindow[] windows = workbench.getWorkbenchWindows();
484                 for (int i = 0; i < windows.length; i++) {
485                         IWorkbenchPage[] pages = windows[i].getPages();
486                         for (int x = 0; x < pages.length; x++) {
487                                 IEditorPart[] editors = pages[x].getDirtyEditors();
488                                 for (int z = 0; z < editors.length; z++) {
489                                         IEditorPart ep = editors[z];
490                                         IEditorInput input = ep.getEditorInput();
491                                         if (!inputs.contains(input)) {
492                                                 inputs.add(input);
493                                                 result.add(ep);
494                                         }
495                                 }
496                         }
497                 }
498                 return (IEditorPart[]) result.toArray(new IEditorPart[result.size()]);
499         }
500
501         public static IWorkbenchWindow getActiveWorkbenchWindow() {
502                 return getDefault().getWorkbench().getActiveWorkbenchWindow();
503         }
504
505         /**
506          * Returns the shared instance.
507          */
508         public static PHPeclipsePlugin getDefault() {
509                 return plugin;
510         }
511
512         public static ImageDescriptorRegistry getImageDescriptorRegistry() {
513                 return getDefault().internalGetImageDescriptorRegistry();
514         }
515
516         static IPath getInstallLocation() {
517                 return new Path(getDefault().getBundle().getEntry("/").getFile());
518         }
519
520         // public static int getJVM() {
521         // return jvm;
522         // }
523
524         public static String getPluginId() {
525                 return getDefault().getBundle().getSymbolicName();
526         }
527
528         /**
529          * Returns the standard display to be used. The method first checks, if the
530          * thread calling this method has an associated display. If so, this display
531          * is returned. Otherwise the method returns the default display.
532          */
533         public static Display getStandardDisplay() {
534                 Display display = Display.getCurrent();
535                 if (display == null) {
536                         display = Display.getDefault();
537                 }
538                 return display;
539         }
540
541         // public static ExternalToolsPlugin getExternalTools() {
542         // return externalTools;
543         // }
544         /**
545          * Returns the workspace instance.
546          */
547         public static IWorkspace getWorkspace() {
548                 return ResourcesPlugin.getWorkspace();
549         }
550
551         public static boolean isDebug() {
552                 return getDefault().isDebugging();
553         }
554
555         // public static void logErrorMessage(String message) {
556         // log(new Status(IStatus.ERROR, getPluginId(),
557         // JavaStatusConstants.INTERNAL_ERROR, message, null));
558         // }
559         //
560         // public static void logErrorStatus(String message, IStatus status) {
561         // if (status == null) {
562         // logErrorMessage(message);
563         // return;
564         // }
565         // MultiStatus multi= new MultiStatus(getPluginId(),
566         // JavaStatusConstants.INTERNAL_ERROR, message, null);
567         // multi.add(status);
568         // log(multi);
569         // }
570         //
571         // public static void log(Throwable e) {
572         // log(new Status(IStatus.ERROR, getPluginId(),
573         // JavaStatusConstants.INTERNAL_ERROR,
574         // JavaUIMessages.getString("JavaPlugin.internal_error"), e)); //$NON-NLS-1$
575         // }
576         public static void log(int severity, String message) {
577                 Status status = new Status(severity, PLUGIN_ID, IStatus.OK, message,
578                                 null);
579                 log(status);
580         }
581
582         public static void log(IStatus status) {
583                 getDefault().getLog().log(status);
584         }
585
586         public static void log(Throwable t) {
587                 log(error(t));
588         }
589
590         public static void log(String message, Throwable t) {
591                 log(error(message, t));
592         }
593
594         public static void logErrorMessage(String message) {
595                 log(new Status(IStatus.ERROR, getPluginId(),
596                                 IJavaStatusConstants.INTERNAL_ERROR, message, null));
597         }
598
599         public static IStatus error(Throwable t) {
600                 return error("PHPeclipsePlugin.internalErrorOccurred", t); //$NON-NLS-1$
601         }
602
603         public static IStatus error(String message, Throwable t) {
604                 return new Status(IStatus.ERROR, PLUGIN_ID, IStatus.ERROR, message, t);
605         }
606
607         // private static void setJVM() {
608         // String osName = System.getProperty("os.name");
609         // if (osName.startsWith("Mac OS")) {
610         // String mrjVersion = System.getProperty("mrj.version");
611         // String majorMRJVersion = mrjVersion.substring(0, 3);
612         // jvm = OTHER;
613         // try {
614         // double version = Double.valueOf(majorMRJVersion).doubleValue();
615         // if (version == 2) {
616         // jvm = MRJ_2_0;
617         // } else if (version >= 2.1 && version < 3) {
618         // jvm = MRJ_2_1;
619         // } else if (version == 3.0) {
620         // jvm = MRJ_3_0;
621         // } else if (version >= 3.1) {
622         // jvm = MRJ_3_1;
623         // }
624         // } catch (NumberFormatException nfe) {
625         // }
626         // } else if (osName.startsWith("Windows")) {
627         // if (osName.indexOf("9") != -1) {
628         // jvm = WINDOWS_9x;
629         // } else {
630         // jvm = WINDOWS_NT;
631         // }
632         // }
633         // }
634
635         // TODO: refactor this into a better method name !
636         public synchronized ICompilationUnitDocumentProvider getCompilationUnitDocumentProvider() {
637                 if (fCompilationUnitDocumentProvider == null)
638                         fCompilationUnitDocumentProvider = new PHPDocumentProvider();
639                 return fCompilationUnitDocumentProvider;
640         }
641
642         /**
643          * Get the identifier index manager for the given project
644          * 
645          * @param iProject
646          *            the current project
647          * @return
648          */
649         public IdentifierIndexManager getIndexManager(IProject iProject) {
650                 IPath path = iProject.getWorkingLocation(PHPeclipsePlugin.PLUGIN_ID);
651                 path = path.append("project.index");
652                 String indexFilename = path.toString();
653                 // try {
654                 // IdentDB db = IdentDB.getInstance();
655                 // } catch (ClassNotFoundException e) {
656                 // e.printStackTrace();
657                 // } catch (SQLException e) {
658                 // e.printStackTrace();
659                 // }
660                 IdentifierIndexManager indexManager = (IdentifierIndexManager) fIndexManagerMap
661                                 .get(indexFilename);
662                 if (indexManager == null) {
663                         indexManager = new IdentifierIndexManager(indexFilename);
664                         fIndexManagerMap.put(indexFilename, indexManager);
665                 }
666                 return indexManager;
667         }
668
669         public synchronized IWorkingCopyManager getWorkingCopyManager() {
670                 if (fWorkingCopyManager == null) {
671                         ICompilationUnitDocumentProvider provider = getCompilationUnitDocumentProvider();
672                         fWorkingCopyManager = new WorkingCopyManager(provider);
673                 }
674                 return fWorkingCopyManager;
675         }
676
677         public synchronized MembersOrderPreferenceCache getMemberOrderPreferenceCache() {
678                 if (fMembersOrderPreferenceCache == null)
679                         fMembersOrderPreferenceCache = new MembersOrderPreferenceCache();
680                 return fMembersOrderPreferenceCache;
681         }
682
683         /**
684          * Returns the mockup preference store for firing events and registering
685          * listeners on project setting changes. Temporary solution.
686          */
687         public MockupPreferenceStore getMockupPreferenceStore() {
688                 if (fMockupPreferenceStore == null)
689                         fMockupPreferenceStore = new MockupPreferenceStore();
690
691                 return fMockupPreferenceStore;
692         }
693
694         public synchronized ProblemMarkerManager getProblemMarkerManager() {
695                 if (fProblemMarkerManager == null)
696                         fProblemMarkerManager = new ProblemMarkerManager();
697                 return fProblemMarkerManager;
698         }
699
700         // public synchronized JavaTextTools getJavaTextTools() {
701         // if (fJavaTextTools == null)
702         // fJavaTextTools = new JavaTextTools(getPreferenceStore());
703         // return fJavaTextTools;
704         // }
705         public synchronized JavaTextTools getJavaTextTools() {
706                 if (fJavaTextTools == null)
707                         fJavaTextTools = new JavaTextTools(getPreferenceStore(), JavaCore
708                                         .getPlugin().getPluginPreferences());
709                 return fJavaTextTools;
710         }
711
712         public IFile getLastEditorFile() {
713                 return fLastEditorFile;
714         }
715
716         /**
717          * Returns the string from the plugin's resource bundle, or 'key' if not
718          * found.
719          */
720         // public static String getResourceString(String key) {
721         // ResourceBundle bundle =
722         // PHPeclipsePlugin.getDefault().getResourceBundle();
723         // try {
724         // return bundle.getString(key);
725         // } catch (MissingResourceException e) {
726         // return key;
727         // }
728         // }
729         /**
730          * Returns the plugin's resource bundle,
731          */
732         // public ResourceBundle getResourceBundle() {
733         // return resourceBundle;
734         // }
735         protected void initializeDefaultPreferences(IPreferenceStore store) {
736                 String operatingSystem = Platform.getOS();
737                 // maxosx, linux, solaris, win32,...
738                 try {
739                         InputStream is = getDefault()
740                                         .openStream(
741                                                         new Path("prefs/default_" + operatingSystem
742                                                                         + ".properties"));
743                         PropertyResourceBundle resourceBundle = new PropertyResourceBundle(
744                                         is);
745                         Enumeration e = resourceBundle.getKeys();
746                         String key;
747                         while (e.hasMoreElements()) {
748                                 key = (String) e.nextElement();
749                                 store.setDefault(key, resourceBundle.getString(key));
750                         }
751                 } catch (Exception e) {
752                         // no default properties found
753                         if (operatingSystem.equals(Platform.OS_WIN32)) {
754                                 // store.setDefault(PHP_RUN_PREF, "c:\\apache\\php\\php.exe");
755                                 // store.setDefault(EXTERNAL_PARSER_PREF, "c:\\apache\\php\\php
756                                 // -l -f {0}");
757                                 // store.setDefault(MYSQL_RUN_PREF,
758                                 // "c:\\apache\\mysql\\bin\\mysqld-nt.exe");
759                                 // store.setDefault(APACHE_RUN_PREF, "c:\\apache\\apache.exe");
760                                 // store.setDefault(XAMPP_START_PREF,
761                                 // "c:\\xampp\\xampp_start.exe");
762                                 // store.setDefault(XAMPP_STOP_PREF,
763                                 // "c:\\xampp\\xampp_stop.exe");
764                                 // store.setDefault(
765                                 // ETC_HOSTS_PATH_PREF,
766                                 // "c:\\windows\\system32\\drivers\\etc\\hosts");
767                         } else {
768                                 // store.setDefault(PHP_RUN_PREF, "/apache/php/php");
769                                 // store.setDefault(EXTERNAL_PARSER_PREF, "/apache/php/php -l -f
770                                 // {0}");
771                                 // store.setDefault(MYSQL_RUN_PREF, "/apache/mysql/bin/mysqld");
772                                 // store.setDefault(APACHE_RUN_PREF, "/apache/apache");
773                                 // store.setDefault(XAMPP_START_PREF, "xamp/xampp_start");
774                                 // store.setDefault(XAMPP_STOP_PREF, "xampp/xampp_stop");
775                         }
776                         // store.setDefault(MYSQL_PREF, "--standalone");
777                         // store.setDefault(APACHE_START_PREF, "-c \"DocumentRoot
778                         // \"{0}\"\"");
779                         // store.setDefault(APACHE_STOP_PREF, "-k shutdown");
780                         // store.setDefault(APACHE_RESTART_PREF, "-k restart");
781                         // store.setDefault(MYSQL_START_BACKGROUND, "true");
782                         // store.setDefault(APACHE_START_BACKGROUND, "true");
783                         // store.setDefault(APACHE_STOP_BACKGROUND, "true");
784                         // store.setDefault(APACHE_RESTART_BACKGROUND, "true");
785                 }
786
787                 // store.setDefault(SHOW_OUTPUT_IN_CONSOLE, "true");
788                 // store.setDefault(PHP_OBFUSCATOR_DEFAULT, "c:\\temp");
789                 // if (operatingSystem.equals(Platform.OS_WIN32)) {
790                 // store.setDefault(EXTERNAL_BROWSER_PREF, "rundll32
791                 // url.dll,FileProtocolHandler {0}");
792                 // } else if (operatingSystem.equals(Platform.OS_MACOSX)) {
793                 // store.setDefault(PHP_OBFUSCATOR_DEFAULT, "/tmp");
794                 // TODO How do we start Safari on Mac OS X ?
795                 // store.setDefault(EXTERNAL_BROWSER_PREF, "netscape {0}");
796                 // } else {
797                 // store.setDefault(PHP_OBFUSCATOR_DEFAULT, "/tmp");
798                 // store.setDefault(EXTERNAL_BROWSER_PREF, "netscape {0}");
799                 // }
800
801                 // store.setDefault(PHP_EXTENSION_PREFS,
802                 // "php,php3,php4,php5,phtml,inc,module,class");
803
804                 // store.setDefault(PHP_PARSER_DEFAULT, PHP_EXTERNAL_PARSER);
805                 // store.setDefault(PHP_INTERNAL_PARSER, "false");
806                 // store.setDefault(PHP_EXTERNAL_PARSER, "true");
807                 // store.setDefault(PHP_PARSE_ON_SAVE, "true");
808                 // show line numbers:
809                 // store.setDefault(LINE_NUMBER_RULER, "false");
810                 // store.setDefault(FORMATTER_TAB_SIZE, "4");
811                 // php syntax highlighting
812                 store.setDefault(PHP_USERDEF_XMLFILE, "");
813                 // assume there is none chooA
814                 // PreferenceConverter.setDefault(store, PHP_MULTILINE_COMMENT,
815                 // PHPColorProvider.MULTI_LINE_COMMENT);
816                 // PreferenceConverter.setDefault(store, PHP_SINGLELINE_COMMENT,
817                 // PHPColorProvider.SINGLE_LINE_COMMENT);
818                 PreferenceConverter.setDefault(store, PHP_TAG, PHPColorProvider.TAG);
819                 PreferenceConverter.setDefault(store, PHP_KEYWORD,
820                                 PHPColorProvider.KEYWORD);
821                 PreferenceConverter.setDefault(store, PHP_VARIABLE,
822                                 PHPColorProvider.VARIABLE);
823                 PreferenceConverter.setDefault(store, PHP_VARIABLE_DOLLAR,
824                                 PHPColorProvider.VARIABLE);
825                 PreferenceConverter.setDefault(store, PHP_FUNCTIONNAME,
826                                 PHPColorProvider.FUNCTION_NAME);
827                 PreferenceConverter.setDefault(store, PHP_CONSTANT,
828                                 PHPColorProvider.CONSTANT);
829                 PreferenceConverter.setDefault(store, PHP_TYPE, PHPColorProvider.TYPE);
830                 // PreferenceConverter.setDefault(store, PHP_STRING_DQ,
831                 // PHPColorProvider.STRING_DQ);
832                 // store.setDefault(PHP_STRING_BOLD_DQ, true);
833                 // PreferenceConverter.setDefault(store, PHP_STRING_SQ,
834                 // PHPColorProvider.STRING_SQ);
835                 PreferenceConverter.setDefault(store, PHP_DEFAULT,
836                                 PHPColorProvider.DEFAULT);
837                 PreferenceConverter.setDefault(store, PHPDOC_KEYWORD,
838                                 PHPColorProvider.PHPDOC_KEYWORD);
839                 PreferenceConverter.setDefault(store, PHPDOC_TAG,
840                                 PHPColorProvider.PHPDOC_TAG);
841                 PreferenceConverter.setDefault(store, PHPDOC_LINK,
842                                 PHPColorProvider.PHPDOC_LINK);
843                 PreferenceConverter.setDefault(store, PHPDOC_DEFAULT,
844                                 PHPColorProvider.PHPDOC_DEFAULT);
845
846                 PreferenceConverter.setDefault(store, EDITOR_PHP_KEYWORD_RETURN_COLOR,
847                                 new RGB(127, 0, 85));
848                 store.setDefault(EDITOR_PHP_KEYWORD_RETURN_BOLD, true);
849                 store.setDefault(EDITOR_PHP_KEYWORD_RETURN_ITALIC, false);
850
851                 PreferenceConverter.setDefault(store, EDITOR_PHP_OPERATOR_COLOR,
852                                 new RGB(0, 0, 0));
853                 store.setDefault(EDITOR_PHP_OPERATOR_BOLD, false);
854                 store.setDefault(EDITOR_PHP_OPERATOR_ITALIC, false);
855
856                 PreferenceConverter.setDefault(store, EDITOR_PHP_BRACE_OPERATOR_COLOR,
857                                 new RGB(0, 0, 0));
858                 store.setDefault(EDITOR_PHP_BRACE_OPERATOR_BOLD, false);
859                 store.setDefault(EDITOR_PHP_BRACE_OPERATOR_ITALIC, false);
860                 // PreferenceConverter.setDefault(
861                 // store,
862                 // PHP_EDITOR_BACKGROUND,
863                 // PHPColorProvider.BACKGROUND);
864                 // PreferenceConverter.setDefault(
865                 // store,
866                 // LINKED_POSITION_COLOR,
867                 // PHPColorProvider.LINKED_POSITION_COLOR);
868                 // PreferenceConverter.setDefault(
869                 // store,
870                 // LINE_NUMBER_COLOR,
871                 // PHPColorProvider.LINE_NUMBER_COLOR);
872                 // // set default PHPDoc colors:
873                 // PreferenceConverter.setDefault(
874                 // store,
875                 // PHPDOC_KEYWORD,
876                 // PHPColorProvider.PHPDOC_KEYWORD);
877                 // PreferenceConverter.setDefault(
878                 // store,
879                 // PHPDOC_LINK,
880                 // PHPColorProvider.PHPDOC_LINK);
881                 // PreferenceConverter.setDefault(
882                 // store,
883                 // PHPDOC_DEFAULT,
884                 // PHPColorProvider.PHPDOC_DEFAULT);
885                 // PreferenceConverter.setDefault(
886                 // store,
887                 // PHPDOC_TAG,
888                 // PHPColorProvider.PHPDOC_TAG);
889                 // store.setDefault(PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT, "true");
890                 // PreferenceConverter.setDefault(
891                 // store,
892                 // PREFERENCE_COLOR_BACKGROUND,
893                 // PHPColorProvider.BACKGROUND_COLOR);
894                 // language stuff
895                 // store.setDefault(RESOURCE_BUNDLE, LANGUAGE_DEFAULT);
896                 // store.setDefault(RESOURCE_BUNDLE_EN_GB, "true");
897                 // store.setDefault(RESOURCE_BUNDLE_DE, "false");
898                 // store.setDefault(RESOURCE_BUNDLE_FR, "false");
899                 // store.setDefault(RESOURCE_BUNDLE_ES, "false");
900                 // TemplatePreferencePage.initDefaults(store);
901                 // this will initialize the static fields in the syntaxrdr class
902                 new PHPSyntaxRdr();
903                 JavaCore.initializeDefaultPluginPreferences();
904                 PreferenceConstants.initializeDefaultValues(store);
905                 // externalTools.initializeDefaultPreferences(store);
906                 MarkerAnnotationPreferences.initializeDefaultValues(store);
907         }
908
909         private IWorkbenchPage internalGetActivePage() {
910                 IWorkbenchWindow window = getWorkbench().getActiveWorkbenchWindow();
911                 if (window != null)
912                         return window.getActivePage();
913                 return null;
914         }
915
916         private ImageDescriptorRegistry internalGetImageDescriptorRegistry() {
917                 if (fImageDescriptorRegistry == null)
918                         fImageDescriptorRegistry = new ImageDescriptorRegistry();
919                 return fImageDescriptorRegistry;
920         }
921
922         /**
923          * Open a file in the Workbench that may or may not exist in the workspace.
924          * Must be run on the UI thread.
925          * 
926          * @param filename
927          * @throws CoreException
928          */
929         public ITextEditor openFileInTextEditor(String filename)
930                         throws CoreException {
931                 // reject directories
932                 if (new File(filename).isDirectory())
933                         return null;
934                 IWorkbench workbench = PlatformUI.getWorkbench();
935                 IWorkbenchWindow window = workbench.getWorkbenchWindows()[0];
936                 IWorkbenchPage page = window.getActivePage();
937                 IPath path = new Path(filename);
938                 // If the file exists in the workspace, open it
939                 IFile file = getWorkspace().getRoot().getFileForLocation(path);
940                 IEditorPart editor;
941                 ITextEditor textEditor;
942                 if (file != null && file.exists()) {
943                         editor = IDE.openEditor(page, file, true);
944                         textEditor = (ITextEditor) editor.getAdapter(ITextEditor.class);
945                 } else {
946                         // Otherwise open the stream directly
947                         if (page == null)
948                                 return null;
949                         FileStorage storage = new FileStorage(path);
950                         IEditorRegistry registry = getWorkbench().getEditorRegistry();
951                         IEditorDescriptor desc = registry.getDefaultEditor(filename);
952                         if (desc == null) {
953                                 desc = registry
954                                                 .findEditor(IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID);
955                                 // desc = registry.getDefaultEditor();
956                         }
957                         IEditorInput input = new ExternalEditorInput(storage);
958                         editor = page.openEditor(input, desc.getId());
959                         textEditor = (ITextEditor) editor.getAdapter(ITextEditor.class);
960                         // If the storage provider is not ours, we can't guarantee
961                         // read/write.
962                         if (textEditor != null) {
963                                 IDocumentProvider documentProvider = textEditor
964                                                 .getDocumentProvider();
965                                 if (!(documentProvider instanceof ExternalStorageDocumentProvider)) {
966                                         storage.setReadOnly();
967                                 }
968                         }
969                 }
970                 return textEditor;
971         }
972
973         /**
974          * Open a file in the Workbench that may or may not exist in the workspace.
975          * Must be run on the UI thread.
976          * 
977          * @param filename
978          * @param line
979          * @throws CoreException
980          */
981         public void openFileAndGotoLine(String filename, int line)
982                         throws CoreException {
983                 ITextEditor textEditor = openFileInTextEditor(filename);
984                 if (textEditor != null) {
985                         // If a line number was given, go to it
986                         if (line > 0) {
987                                 try {
988                                         line--; // document is 0 based
989                                         IDocument document = textEditor.getDocumentProvider()
990                                                         .getDocument(textEditor.getEditorInput());
991                                         textEditor.selectAndReveal(document.getLineOffset(line),
992                                                         document.getLineLength(line));
993                                 } catch (BadLocationException e) {
994                                         // invalid text position -> do nothing
995                                 }
996                         }
997                 }
998         }
999
1000         /**
1001          * Open a file in the Workbench that may or may not exist in the workspace.
1002          * Must be run on the UI thread.
1003          * 
1004          * @param filename
1005          * @param offset
1006          * @throws CoreException
1007          */
1008         public void openFileAndGotoOffset(String filename, int offset, int length)
1009                         throws CoreException {
1010                 ITextEditor textEditor = openFileInTextEditor(filename);
1011                 if (textEditor != null) {
1012                         // If a line number was given, go to it
1013                         if (offset >= 0) {
1014                                 IDocument document = textEditor.getDocumentProvider()
1015                                                 .getDocument(textEditor.getEditorInput());
1016                                 textEditor.selectAndReveal(offset, length);
1017                         }
1018                 }
1019         }
1020
1021         public void openFileAndFindString(String filename, String findString)
1022                         throws CoreException {
1023                 ITextEditor textEditor = openFileInTextEditor(filename);
1024                 if (textEditor != null) {
1025                         // If a string was given, go to it
1026                         if (findString != null) {
1027                                 try {
1028                                         IDocument document = textEditor.getDocumentProvider()
1029                                                         .getDocument(textEditor.getEditorInput());
1030                                         int offset = document.search(0, findString, true, false,
1031                                                         true);
1032                                         textEditor.selectAndReveal(offset, findString.length());
1033                                 } catch (BadLocationException e) {
1034                                         // invalid text position -> do nothing
1035                                 }
1036                         }
1037                 }
1038         }
1039
1040         public void setLastEditorFile(IFile textEditor) {
1041                 this.fLastEditorFile = textEditor;
1042         }
1043
1044         /*
1045          * @see org.eclipse.core.runtime.Plugin#stop
1046          */
1047         public void stop(BundleContext context) throws Exception {
1048                 try {
1049                         // JavaCore.stop(this, context);
1050                         plugin.savePluginPreferences();
1051                         IWorkspace workspace = ResourcesPlugin.getWorkspace();
1052                         workspace.removeResourceChangeListener(JavaModelManager
1053                                         .getJavaModelManager().deltaState);
1054                         workspace.removeSaveParticipant(plugin);
1055
1056                         JavaModelManager.getJavaModelManager().shutdown();
1057
1058                         // save the information from the php index files if necessary
1059                         Collection collection = fIndexManagerMap.values();
1060                         Iterator iterator = collection.iterator();
1061                         IdentifierIndexManager indexManager = null;
1062                         while (iterator.hasNext()) {
1063                                 indexManager = (IdentifierIndexManager) iterator.next();
1064                                 indexManager.writeFile();
1065                         }
1066                         if (fImageDescriptorRegistry != null)
1067                                 fImageDescriptorRegistry.dispose();
1068
1069                         // AllTypesCache.terminate();
1070
1071                         if (fImageDescriptorRegistry != null)
1072                                 fImageDescriptorRegistry.dispose();
1073
1074                         unregisterAdapters();
1075
1076                         // if (fASTProvider != null) {
1077                         // fASTProvider.dispose();
1078                         // fASTProvider= null;
1079                         // }
1080
1081                         if (fWorkingCopyManager != null) {
1082                                 fWorkingCopyManager.shutdown();
1083                                 fWorkingCopyManager = null;
1084                         }
1085
1086                         if (fCompilationUnitDocumentProvider != null) {
1087                                 fCompilationUnitDocumentProvider.shutdown();
1088                                 fCompilationUnitDocumentProvider = null;
1089                         }
1090
1091                         if (fJavaTextTools != null) {
1092                                 fJavaTextTools.dispose();
1093                                 fJavaTextTools = null;
1094                         }
1095                         // JavaDocLocations.shutdownJavadocLocations();
1096
1097                         uninstallPreferenceStoreBackwardsCompatibility();
1098
1099                         // RefactoringCore.getUndoManager().shutdown();
1100                 } finally {
1101                         super.stop(context);
1102                 }
1103         }
1104
1105         /**
1106          * @see org.eclipse.ui.plugin.AbstractUIPlugin#shutdown()
1107          */
1108         // public void shutdown() throws CoreException {
1109         // // moved down (see below):
1110         // // super.shutdown();
1111         // // externalTools.shutDown();
1112         // ColorManager.getDefault().dispose();
1113         // // save the information from the php index files if necessary
1114         // Collection collection = fIndexManagerMap.values();
1115         // Iterator iterator = collection.iterator();
1116         // IdentifierIndexManager indexManager = null;
1117         // while (iterator.hasNext()) {
1118         // indexManager = (IdentifierIndexManager) iterator.next();
1119         // indexManager.writeFile();
1120         // }
1121         // if (fImageDescriptorRegistry != null)
1122         // fImageDescriptorRegistry.dispose();
1123         // // unregisterAdapters();
1124         // super.shutdown();
1125         // if (fWorkingCopyManager != null) {
1126         // fWorkingCopyManager.shutdown();
1127         // fWorkingCopyManager = null;
1128         // }
1129         // if (fCompilationUnitDocumentProvider != null) {
1130         // fCompilationUnitDocumentProvider.shutdown();
1131         // fCompilationUnitDocumentProvider = null;
1132         // }
1133         // if (fJavaTextTools != null) {
1134         // fJavaTextTools.dispose();
1135         // fJavaTextTools = null;
1136         // }
1137         // // JavaDocLocations.shutdownJavadocLocations();
1138         // //
1139         // //
1140         // JFaceResources.getFontRegistry().removeListener(fFontPropertyChangeListener);
1141         // // begin JavaCore#shutdown()
1142         // //savePluginPreferences();
1143         // savePluginPreferences();
1144         // IWorkspace workspace = ResourcesPlugin.getWorkspace();
1145         // workspace.removeResourceChangeListener(JavaModelManager.getJavaModelManager().deltaState);
1146         // workspace.removeSaveParticipant(this);
1147         // ((JavaModelManager) JavaModelManager.getJavaModelManager()).shutdown();
1148         // // end JavaCore#shutdown()
1149         // }
1150         /**
1151          * Installs backwards compatibility for the preference store.
1152          */
1153         private void installPreferenceStoreBackwardsCompatibility() {
1154
1155                 /*
1156                  * Installs backwards compatibility: propagate the Java editor font from
1157                  * a pre-2.1 plug-in to the Platform UI's preference store to preserve
1158                  * the Java editor font from a pre-2.1 workspace. This is done only
1159                  * once.
1160                  */
1161                 String fontPropagatedKey = "fontPropagated"; //$NON-NLS-1$
1162                 if (getPreferenceStore().contains(JFaceResources.TEXT_FONT)
1163                                 && !getPreferenceStore().isDefault(JFaceResources.TEXT_FONT)) {
1164                         if (!getPreferenceStore().getBoolean(fontPropagatedKey))
1165                                 PreferenceConverter
1166                                                 .setValue(PlatformUI.getWorkbench()
1167                                                                 .getPreferenceStore(),
1168                                                                 PreferenceConstants.EDITOR_TEXT_FONT,
1169                                                                 PreferenceConverter.getFontDataArray(
1170                                                                                 getPreferenceStore(),
1171                                                                                 JFaceResources.TEXT_FONT));
1172                 }
1173                 getPreferenceStore().setValue(fontPropagatedKey, true);
1174
1175                 /*
1176                  * Backwards compatibility: set the Java editor font in this plug-in's
1177                  * preference store to let older versions access it. Since 2.1 the Java
1178                  * editor font is managed by the workbench font preference page.
1179                  */
1180                 PreferenceConverter.putValue(getPreferenceStore(),
1181                                 JFaceResources.TEXT_FONT, JFaceResources.getFontRegistry()
1182                                                 .getFontData(PreferenceConstants.EDITOR_TEXT_FONT));
1183
1184                 fFontPropertyChangeListener = new IPropertyChangeListener() {
1185                         public void propertyChange(PropertyChangeEvent event) {
1186                                 if (PreferenceConstants.EDITOR_TEXT_FONT.equals(event
1187                                                 .getProperty()))
1188                                         PreferenceConverter.putValue(getPreferenceStore(),
1189                                                         JFaceResources.TEXT_FONT,
1190                                                         JFaceResources.getFontRegistry().getFontData(
1191                                                                         PreferenceConstants.EDITOR_TEXT_FONT));
1192                         }
1193                 };
1194                 JFaceResources.getFontRegistry().addListener(
1195                                 fFontPropertyChangeListener);
1196
1197                 /*
1198                  * Backwards compatibility: propagate the Java editor tab width from a
1199                  * pre-3.0 plug-in to the new preference key. This is done only once.
1200                  */
1201                 // final String oldTabWidthKey = PreferenceConstants.EDITOR_TAB_WIDTH;
1202                 // final String newTabWidthKey =
1203                 // AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH;
1204                 // String tabWidthPropagatedKey = "tabWidthPropagated"; //$NON-NLS-1$
1205                 // if (getPreferenceStore().contains(oldTabWidthKey) &&
1206                 // !getPreferenceStore().isDefault(oldTabWidthKey)) {
1207                 // if (!getPreferenceStore().getBoolean(tabWidthPropagatedKey))
1208                 // getPreferenceStore().setValue(newTabWidthKey,
1209                 // getPreferenceStore().getInt(oldTabWidthKey));
1210                 // }
1211                 // getPreferenceStore().setValue(tabWidthPropagatedKey, true);
1212                 //
1213                 // /*
1214                 // * Backwards compatibility: set the Java editor tab width in this
1215                 // plug-in's preference store with the old key to let older
1216                 // * versions access it. Since 3.0 the tab width is managed by the
1217                 // extended texteditor and uses a new key.
1218                 // */
1219                 // getPreferenceStore().putValue(oldTabWidthKey,
1220                 // getPreferenceStore().getString(newTabWidthKey));
1221                 // fPropertyChangeListener = new IPropertyChangeListener() {
1222                 // public void propertyChange(PropertyChangeEvent event) {
1223                 // if (newTabWidthKey.equals(event.getProperty()))
1224                 // getPreferenceStore().putValue(oldTabWidthKey,
1225                 // getPreferenceStore().getString(newTabWidthKey));
1226                 // }
1227                 // };
1228                 // getPreferenceStore().addPropertyChangeListener(fPropertyChangeListener);
1229                 /*
1230                  * Backward compatibility for the refactoring preference key.
1231                  */
1232                 // getPreferenceStore().setValue(
1233                 // PreferenceConstants.REFACTOR_ERROR_PAGE_SEVERITY_THRESHOLD,
1234                 // RefactoringCore.getConditionCheckingFailedSeverity());
1235         }
1236
1237         /**
1238          * Uninstalls backwards compatibility for the preference store.
1239          */
1240         private void uninstallPreferenceStoreBackwardsCompatibility() {
1241                 JFaceResources.getFontRegistry().removeListener(
1242                                 fFontPropertyChangeListener);
1243                 // getPreferenceStore().removePropertyChangeListener(fPropertyChangeListener);
1244         }
1245
1246         /*
1247          * (non - Javadoc) Method declared in Plugin
1248          */
1249         public void start(BundleContext context) throws Exception {
1250                 super.start(context);
1251
1252                 // JavaCore.start(this, context);
1253                 final JavaModelManager modelManager = JavaModelManager
1254                                 .getJavaModelManager();
1255                 try {
1256                         modelManager.configurePluginDebugOptions();
1257
1258                         // request state folder creation (workaround 19885)
1259                         // JavaCore.getPlugin().getStateLocation();
1260                         getStateLocation();
1261                         // retrieve variable values
1262                         PHPeclipsePlugin.getDefault().getPluginPreferences()
1263                                         .addPropertyChangeListener(
1264                                                         new JavaModelManager.PluginPreferencesListener());
1265                         // manager.loadVariablesAndContainers();
1266
1267                         final IWorkspace workspace = ResourcesPlugin.getWorkspace();
1268                         workspace.addResourceChangeListener(modelManager.deltaState,
1269                                         IResourceChangeEvent.PRE_BUILD
1270                                                         | IResourceChangeEvent.POST_BUILD
1271                                                         | IResourceChangeEvent.POST_CHANGE
1272                                                         | IResourceChangeEvent.PRE_DELETE
1273                                                         | IResourceChangeEvent.PRE_CLOSE);
1274
1275                         // startIndexing();
1276                         ISavedState savedState = workspace.addSaveParticipant(
1277                                         PHPeclipsePlugin.this, modelManager);
1278
1279                         // process deltas since last activated in indexer thread so that
1280                         // indexes are up-to-date.
1281                         // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=38658
1282                         Job processSavedState = new Job(Util.bind("savedState.jobName")) { //$NON-NLS-1$
1283                                 protected IStatus run(IProgressMonitor monitor) {
1284                                         try {
1285                                                 // add save participant and process delta atomically
1286                                                 // see
1287                                                 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=59937
1288                                                 workspace.run(new IWorkspaceRunnable() {
1289                                                         public void run(IProgressMonitor progress)
1290                                                                         throws CoreException {
1291                                                                 ISavedState savedState = workspace
1292                                                                                 .addSaveParticipant(
1293                                                                                                 PHPeclipsePlugin.this,
1294                                                                                                 modelManager);
1295                                                                 if (savedState != null) {
1296                                                                         // the event type coming from the saved
1297                                                                         // state is always POST_AUTO_BUILD
1298                                                                         // force it to be POST_CHANGE so that the
1299                                                                         // delta processor can handle it
1300                                                                         modelManager.deltaState.getDeltaProcessor().overridenEventType = IResourceChangeEvent.POST_CHANGE;
1301                                                                         savedState
1302                                                                                         .processResourceChangeEvents(modelManager.deltaState);
1303                                                                 }
1304                                                         }
1305                                                 }, monitor);
1306                                         } catch (CoreException e) {
1307                                                 return e.getStatus();
1308                                         }
1309                                         return Status.OK_STATUS;
1310                                 }
1311                         };
1312                         processSavedState.setSystem(true);
1313                         processSavedState.setPriority(Job.SHORT); // process asap
1314                         processSavedState.schedule();
1315                 } catch (RuntimeException e) {
1316                         modelManager.shutdown();
1317                         throw e;
1318                 }
1319
1320                 registerAdapters();
1321
1322                 // if (USE_WORKING_COPY_OWNERS) {
1323                 WorkingCopyOwner.setPrimaryBufferProvider(new WorkingCopyOwner() {
1324                         public IBuffer createBuffer(ICompilationUnit workingCopy) {
1325                                 ICompilationUnit original = workingCopy.getPrimary();
1326                                 IResource resource = original.getResource();
1327                                 if (resource instanceof IFile)
1328                                         return new DocumentAdapter(workingCopy, (IFile) resource);
1329                                 return DocumentAdapter.NULL;
1330                         }
1331                 });
1332                 // }
1333
1334                 installPreferenceStoreBackwardsCompatibility();
1335
1336         }
1337
1338         // registerAdapters();
1339         //
1340         // // externalTools.startUp();
1341         // getStandardDisplay().asyncExec(new Runnable() {
1342         // public void run() {
1343         // //initialize the variable context manager
1344         // VariableContextManager.getDefault();
1345         // }
1346         // });
1347         //
1348         // // if (USE_WORKING_COPY_OWNERS) {
1349         // WorkingCopyOwner.setPrimaryBufferProvider(new WorkingCopyOwner() {
1350         // public IBuffer createBuffer(ICompilationUnit workingCopy) {
1351         // ICompilationUnit original = workingCopy.getPrimary();
1352         // IResource resource = original.getResource();
1353         // if (resource instanceof IFile)
1354         // return new DocumentAdapter(workingCopy, (IFile) resource);
1355         // return DocumentAdapter.NULL;
1356         // }
1357         // });
1358         // // }
1359
1360         // installPreferenceStoreBackwardsCompatibility();
1361
1362         // AllTypesCache.initialize();
1363
1364         // Initialize AST provider
1365         // getASTProvider();
1366         // }
1367
1368         // public void startup() throws CoreException {
1369         // super.startup();
1370         // // begin JavaCore.startup();
1371         // JavaModelManager manager = JavaModelManager.getJavaModelManager();
1372         // try {
1373         // manager.configurePluginDebugOptions();
1374         // // request state folder creation (workaround 19885)
1375         // // JavaCore.getPlugin().getStateLocation();
1376         // getStateLocation();
1377         // // retrieve variable values
1378         // //
1379         // JavaCore.getPlugin().getPluginPreferences().addPropertyChangeListener(new
1380         // // JavaModelManager.PluginPreferencesListener());
1381         // getPluginPreferences().addPropertyChangeListener(
1382         // new JavaModelManager.PluginPreferencesListener());
1383         // // TODO temp-del
1384         // // manager.loadVariablesAndContainers();
1385         // final IWorkspace workspace = ResourcesPlugin.getWorkspace();
1386         // workspace.addResourceChangeListener(
1387         // manager.deltaState,
1388         // IResourceChangeEvent.PRE_BUILD
1389         // | IResourceChangeEvent.POST_BUILD
1390         // | IResourceChangeEvent.POST_CHANGE
1391         // | IResourceChangeEvent.PRE_DELETE
1392         // | IResourceChangeEvent.PRE_CLOSE);
1393         // // startIndexing();
1394         // workspace.addSaveParticipant(PHPeclipsePlugin.getDefault(), manager);
1395         // } catch (CoreException e) {
1396         // } catch (RuntimeException e) {
1397         // manager.shutdown();
1398         // throw e;
1399         // }
1400         // // end JavaCore.startup();
1401         // IAdapterManager platformManager = Platform.getAdapterManager();
1402         // platformManager.registerAdapters(new PHPElementAdapterFactory(),
1403         // PHPElement.class);
1404         // platformManager.registerAdapters(new ResourceAdapterFactory(),
1405         // IResource.class);
1406         // // externalTools.startUp();
1407         // getStandardDisplay().asyncExec(new Runnable() {
1408         // public void run() {
1409         // //initialize the variable context manager
1410         // VariableContextManager.getDefault();
1411         // }
1412         // });
1413         // }
1414
1415         private void registerAdapters() {
1416                 fJavaElementAdapterFactory = new JavaElementAdapterFactory();
1417                 // fMarkerAdapterFactory= new MarkerAdapterFactory();
1418                 // fEditorInputAdapterFactory= new EditorInputAdapterFactory();
1419                 fResourceAdapterFactory = new ResourceAdapterFactory();
1420                 // fLogicalPackageAdapterFactory= new LogicalPackageAdapterFactory();
1421
1422                 IAdapterManager manager = Platform.getAdapterManager();
1423                 manager
1424                                 .registerAdapters(fJavaElementAdapterFactory,
1425                                                 IJavaElement.class);
1426                 // manager.registerAdapters(fMarkerAdapterFactory, IMarker.class);
1427                 // manager.registerAdapters(fEditorInputAdapterFactory,
1428                 // IEditorInput.class);
1429                 manager.registerAdapters(fResourceAdapterFactory, IResource.class);
1430                 // manager.registerAdapters(fLogicalPackageAdapterFactory,
1431                 // LogicalPackage.class);
1432         }
1433
1434         private void unregisterAdapters() {
1435                 IAdapterManager manager = Platform.getAdapterManager();
1436                 manager.unregisterAdapters(fJavaElementAdapterFactory);
1437                 // manager.unregisterAdapters(fMarkerAdapterFactory);
1438                 // manager.unregisterAdapters(fEditorInputAdapterFactory);
1439                 manager.unregisterAdapters(fResourceAdapterFactory);
1440                 // manager.unregisterAdapters(fLogicalPackageAdapterFactory);
1441         }
1442
1443         /**
1444          * Returns a combined preference store, this store is read-only.
1445          * 
1446          * @return the combined preference store
1447          * 
1448          * @since 3.0
1449          */
1450         public IPreferenceStore getCombinedPreferenceStore() {
1451                 if (fCombinedPreferenceStore == null) {
1452                         IPreferenceStore generalTextStore = EditorsUI.getPreferenceStore();
1453                         fCombinedPreferenceStore = new ChainedPreferenceStore(
1454                                         new IPreferenceStore[] {
1455                                                         getPreferenceStore(),
1456                                                         new PreferencesAdapter(PHPeclipsePlugin
1457                                                                         .getDefault().getPluginPreferences()),
1458                                                         generalTextStore });
1459                 }
1460                 return fCombinedPreferenceStore;
1461         }
1462
1463         public synchronized IBufferFactory getBufferFactory() {
1464                 if (fBufferFactory == null)
1465                         fBufferFactory = new CustomBufferFactory();
1466                 return fBufferFactory;
1467         }
1468
1469         /**
1470          * Returns the registry of the extensions to the
1471          * <code>net.sourceforge.phpdt.ui.javaFoldingStructureProvider</code>
1472          * extension point.
1473          * 
1474          * @return the registry of contributed
1475          *         <code>IJavaFoldingStructureProvider</code>
1476          * @since 3.0
1477          */
1478         public synchronized JavaFoldingStructureProviderRegistry getFoldingStructureProviderRegistry() {
1479                 if (fFoldingStructureProviderRegistry == null)
1480                         fFoldingStructureProviderRegistry = new JavaFoldingStructureProviderRegistry();
1481                 return fFoldingStructureProviderRegistry;
1482         }
1483
1484         /**
1485          * Runs the given action as an atomic Java model operation.
1486          * <p>
1487          * After running a method that modifies java elements, registered listeners
1488          * receive after-the-fact notification of what just transpired, in the form
1489          * of a element changed event. This method allows clients to call a number
1490          * of methods that modify java elements and only have element changed event
1491          * notifications reported at the end of the entire batch.
1492          * </p>
1493          * <p>
1494          * If this method is called outside the dynamic scope of another such call,
1495          * this method runs the action and then reports a single element changed
1496          * event describing the net effect of all changes done to java elements by
1497          * the action.
1498          * </p>
1499          * <p>
1500          * If this method is called in the dynamic scope of another such call, this
1501          * method simply runs the action.
1502          * </p>
1503          * 
1504          * @param action
1505          *            the action to perform
1506          * @param monitor
1507          *            a progress monitor, or <code>null</code> if progress
1508          *            reporting and cancellation are not desired
1509          * @exception CoreException
1510          *                if the operation failed.
1511          * @since 2.1
1512          */
1513         public static void run(IWorkspaceRunnable action, IProgressMonitor monitor)
1514                         throws CoreException {
1515                 run(action, ResourcesPlugin.getWorkspace().getRoot(), monitor);
1516         }
1517
1518         /**
1519          * Runs the given action as an atomic Java model operation.
1520          * <p>
1521          * After running a method that modifies java elements, registered listeners
1522          * receive after-the-fact notification of what just transpired, in the form
1523          * of a element changed event. This method allows clients to call a number
1524          * of methods that modify java elements and only have element changed event
1525          * notifications reported at the end of the entire batch.
1526          * </p>
1527          * <p>
1528          * If this method is called outside the dynamic scope of another such call,
1529          * this method runs the action and then reports a single element changed
1530          * event describing the net effect of all changes done to java elements by
1531          * the action.
1532          * </p>
1533          * <p>
1534          * If this method is called in the dynamic scope of another such call, this
1535          * method simply runs the action.
1536          * </p>
1537          * <p>
1538          * The supplied scheduling rule is used to determine whether this operation
1539          * can be run simultaneously with workspace changes in other threads. See
1540          * <code>IWorkspace.run(...)</code> for more details.
1541          * </p>
1542          * 
1543          * @param action
1544          *            the action to perform
1545          * @param rule
1546          *            the scheduling rule to use when running this operation, or
1547          *            <code>null</code> if there are no scheduling restrictions
1548          *            for this operation.
1549          * @param monitor
1550          *            a progress monitor, or <code>null</code> if progress
1551          *            reporting and cancellation are not desired
1552          * @exception CoreException
1553          *                if the operation failed.
1554          * @since 3.0
1555          */
1556         public static void run(IWorkspaceRunnable action, ISchedulingRule rule,
1557                         IProgressMonitor monitor) throws CoreException {
1558                 IWorkspace workspace = ResourcesPlugin.getWorkspace();
1559                 if (workspace.isTreeLocked()) {
1560                         new BatchOperation(action).run(monitor);
1561                 } else {
1562                         // use IWorkspace.run(...) to ensure that a build will be done in
1563                         // autobuild mode
1564                         workspace.run(new BatchOperation(action), rule,
1565                                         IWorkspace.AVOID_UPDATE, monitor);
1566                 }
1567         }
1568
1569         /**
1570          * Returns the template context type registry for the java plugin.
1571          * 
1572          * @return the template context type registry for the java plugin
1573          * @since 3.0
1574          */
1575         public ContextTypeRegistry getTemplateContextRegistry() {
1576                 if (fContextTypeRegistry == null) {
1577                         fContextTypeRegistry = new ContributionContextTypeRegistry();
1578
1579                         fContextTypeRegistry.addContextType(new JavaContextType());
1580                         fContextTypeRegistry.addContextType(new JavaDocContextType());
1581                         fContextTypeRegistry.addContextType(new HTMLContextType());
1582                 }
1583
1584                 return fContextTypeRegistry;
1585         }
1586
1587         /**
1588          * Returns the template store for the java editor templates.
1589          * 
1590          * @return the template store for the java editor templates
1591          * @since 3.0
1592          */
1593         public TemplateStore getTemplateStore() {
1594                 if (fTemplateStore == null) {
1595                         // boolean alreadyMigrated=
1596                         // getPreferenceStore().getBoolean(TEMPLATES_MIGRATION_KEY);
1597                         // if (alreadyMigrated)
1598                         fTemplateStore = new ContributionTemplateStore(
1599                                         getTemplateContextRegistry(), getPreferenceStore(),
1600                                         TEMPLATES_KEY);
1601                         // else {
1602                         // fTemplateStore= new
1603                         // CompatibilityTemplateStore(getTemplateContextRegistry(),
1604                         // getPreferenceStore(), TEMPLATES_KEY,
1605                         // Templates.getInstance());
1606                         // getPreferenceStore().setValue(TEMPLATES_MIGRATION_KEY, true);
1607                         // }
1608
1609                         try {
1610                                 fTemplateStore.load();
1611                         } catch (IOException e) {
1612                                 log(e);
1613                         }
1614                 }
1615
1616                 return fTemplateStore;
1617         }
1618
1619         /**
1620          * Returns the template context type registry for the code generation
1621          * templates.
1622          * 
1623          * @return the template context type registry for the code generation
1624          *         templates
1625          * @since 3.0
1626          */
1627         public ContextTypeRegistry getCodeTemplateContextRegistry() {
1628                 if (fCodeTemplateContextTypeRegistry == null) {
1629                         fCodeTemplateContextTypeRegistry = new ContributionContextTypeRegistry();
1630
1631                         CodeTemplateContextType
1632                                         .registerContextTypes(fCodeTemplateContextTypeRegistry);
1633                 }
1634
1635                 return fCodeTemplateContextTypeRegistry;
1636         }
1637
1638         /**
1639          * Returns the template store for the code generation templates.
1640          * 
1641          * @return the template store for the code generation templates
1642          * @since 3.0
1643          */
1644         public TemplateStore getCodeTemplateStore() {
1645                 if (fCodeTemplateStore == null) {
1646                         // boolean alreadyMigrated=
1647                         // getPreferenceStore().getBoolean(CODE_TEMPLATES_MIGRATION_KEY);
1648                         // if (alreadyMigrated)
1649                         fCodeTemplateStore = new ContributionTemplateStore(
1650                                         getCodeTemplateContextRegistry(), getPreferenceStore(),
1651                                         CODE_TEMPLATES_KEY);
1652                         // else {
1653                         // fCodeTemplateStore= new
1654                         // CompatibilityTemplateStore(getCodeTemplateContextRegistry(),
1655                         // getPreferenceStore(),
1656                         // CODE_TEMPLATES_KEY, CodeTemplates.getInstance());
1657                         // getPreferenceStore().setValue(CODE_TEMPLATES_MIGRATION_KEY,
1658                         // true);
1659                         // }
1660
1661                         try {
1662                                 fCodeTemplateStore.load();
1663                         } catch (IOException e) {
1664                                 log(e);
1665                         }
1666
1667                         // compatibility / bug fixing code for duplicated templates
1668                         // TODO remove for 3.0
1669                         // CompatibilityTemplateStore.pruneDuplicates(fCodeTemplateStore,
1670                         // true);
1671                 }
1672
1673                 return fCodeTemplateStore;
1674         }
1675 }