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