KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > registry > EditorRegistry


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ui.internal.registry;
12
13 import java.io.BufferedReader JavaDoc;
14 import java.io.FileInputStream JavaDoc;
15 import java.io.IOException JavaDoc;
16 import java.io.InputStreamReader JavaDoc;
17 import java.io.Reader JavaDoc;
18 import java.io.StringReader JavaDoc;
19 import java.io.StringWriter JavaDoc;
20 import java.io.Writer JavaDoc;
21 import java.util.ArrayList JavaDoc;
22 import java.util.Arrays JavaDoc;
23 import java.util.Collection JavaDoc;
24 import java.util.Collections JavaDoc;
25 import java.util.Comparator JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.List JavaDoc;
29 import java.util.Map JavaDoc;
30 import java.util.StringTokenizer JavaDoc;
31
32 import org.eclipse.core.commands.common.EventManager;
33 import org.eclipse.core.runtime.IConfigurationElement;
34 import org.eclipse.core.runtime.IExtension;
35 import org.eclipse.core.runtime.IExtensionPoint;
36 import org.eclipse.core.runtime.IPath;
37 import org.eclipse.core.runtime.Platform;
38 import org.eclipse.core.runtime.content.IContentType;
39 import org.eclipse.core.runtime.dynamichelpers.ExtensionTracker;
40 import org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler;
41 import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
42 import org.eclipse.jface.dialogs.ErrorDialog;
43 import org.eclipse.jface.dialogs.MessageDialog;
44 import org.eclipse.jface.preference.IPreferenceStore;
45 import org.eclipse.jface.resource.ImageDescriptor;
46 import org.eclipse.jface.util.SafeRunnable;
47 import org.eclipse.swt.program.Program;
48 import org.eclipse.swt.widgets.Shell;
49 import org.eclipse.ui.IEditorDescriptor;
50 import org.eclipse.ui.IEditorRegistry;
51 import org.eclipse.ui.IFileEditorMapping;
52 import org.eclipse.ui.IMemento;
53 import org.eclipse.ui.IPropertyListener;
54 import org.eclipse.ui.ISharedImages;
55 import org.eclipse.ui.PlatformUI;
56 import org.eclipse.ui.WorkbenchException;
57 import org.eclipse.ui.XMLMemento;
58 import org.eclipse.ui.activities.WorkbenchActivityHelper;
59 import org.eclipse.ui.internal.IPreferenceConstants;
60 import org.eclipse.ui.internal.IWorkbenchConstants;
61 import org.eclipse.ui.internal.IWorkbenchGraphicConstants;
62 import org.eclipse.ui.internal.WorkbenchImages;
63 import org.eclipse.ui.internal.WorkbenchMessages;
64 import org.eclipse.ui.internal.WorkbenchPlugin;
65 import org.eclipse.ui.internal.editorsupport.ComponentSupport;
66 import org.eclipse.ui.internal.misc.ExternalProgramImageDescriptor;
67 import org.eclipse.ui.internal.misc.ProgramImageDescriptor;
68 import org.eclipse.ui.internal.util.Util;
69
70 import com.ibm.icu.text.Collator;
71
72 /**
73  * Provides access to the collection of defined editors for resource types.
74  */

75 public class EditorRegistry extends EventManager implements IEditorRegistry,
76         IExtensionChangeHandler {
77     
78     private final static IEditorDescriptor [] EMPTY = new IEditorDescriptor[0];
79     
80     class RelatedRegistry {
81
82         /**
83          * Return the objects related to the type.
84          *
85          * @param type
86          * @return the objects related to the type
87          */

88         public IEditorDescriptor[] getRelatedObjects(IContentType type) {
89             IEditorDescriptor[] relatedObjects = (IEditorDescriptor[]) contentTypeToEditorMappings.get(type);
90             if (relatedObjects == null) {
91                 return EMPTY;
92             }
93             return relatedObjects;
94         }
95
96         /**
97          * Return the objects related to the filename
98          * @param fileName
99          * @return the objects related to the filename
100          */

101         public IEditorDescriptor[] getRelatedObjects(String JavaDoc fileName) {
102             IFileEditorMapping mapping = getMappingFor(fileName);
103             if (mapping == null) {
104                 return EMPTY;
105             }
106             
107             return mapping.getEditors();
108         }
109         
110     }
111     
112     private Map JavaDoc contentTypeToEditorMappings = new HashMap JavaDoc();
113     
114     /*
115      * Cached images - these include images from registered editors (via
116      * plugins) and others hence this table is not one to one with the mappings
117      * table. It is in fact a superset of the keys one would find in
118      * typeEditorMappings
119      */

120     private Map JavaDoc extensionImages = new HashMap JavaDoc();
121
122     /**
123      * Vector of EditorDescriptor - all the editors loaded from plugin files.
124      * The list is kept in order to be able to show in the editor selection
125      * dialog of the resource associations page. This list is sorted based on the
126      * human readable label of the editor descriptor.
127      *
128      * @see #comparer
129      */

130     private List JavaDoc sortedEditorsFromPlugins = new ArrayList JavaDoc();
131
132     // Map of EditorDescriptor - map editor id to editor.
133
private Map JavaDoc mapIDtoEditor = initialIdToEditorMap(10);
134
135     // Map of FileEditorMapping (extension to FileEditorMapping)
136
private EditorMap typeEditorMappings;
137
138     /*
139      * Compares the labels from two IEditorDescriptor objects
140      */

141     private static final Comparator JavaDoc comparer = new Comparator JavaDoc() {
142         private Collator collator = Collator.getInstance();
143
144         public int compare(Object JavaDoc arg0, Object JavaDoc arg1) {
145             String JavaDoc s1 = ((IEditorDescriptor) arg0).getLabel();
146             String JavaDoc s2 = ((IEditorDescriptor) arg1).getLabel();
147             return collator.compare(s1, s2);
148         }
149     };
150
151     private RelatedRegistry relatedRegistry;
152
153     public static final String JavaDoc EMPTY_EDITOR_ID = "org.eclipse.ui.internal.emptyEditorTab"; //$NON-NLS-1$
154

155     /**
156      * Return an instance of the receiver. Adds listeners into the extension
157      * registry for dynamic UI purposes.
158      */

159     public EditorRegistry() {
160         super();
161         initializeFromStorage();
162         IExtensionTracker tracker = PlatformUI.getWorkbench().getExtensionTracker();
163         tracker.registerHandler(this, ExtensionTracker.createExtensionPointFilter(getExtensionPointFilter()));
164         relatedRegistry = new RelatedRegistry();
165     }
166
167     /**
168      * Add an editor for the given extensions with the specified (possibly null)
169      * extended type. The editor is being registered from a plugin
170      *
171      * @param editor
172      * The description of the editor (as obtained from the plugin
173      * file and built by the registry reader)
174      * @param extensions
175      * Collection of file extensions the editor applies to
176      * @param filenames
177      * Collection of filenames the editor applies to
178      * @param contentTypeVector
179      * @param bDefault
180      * Indicates whether the editor should be made the default editor
181      * and hence appear first inside a FileEditorMapping
182      *
183      * This method is not API and should not be called outside the workbench
184      * code.
185      */

186     public void addEditorFromPlugin(EditorDescriptor editor, List JavaDoc extensions,
187             List JavaDoc filenames, List JavaDoc contentTypeVector, boolean bDefault) {
188
189         PlatformUI.getWorkbench().getExtensionTracker().registerObject(
190                 editor.getConfigurationElement().getDeclaringExtension(),
191                 editor, IExtensionTracker.REF_WEAK);
192         // record it in our quick reference list
193
sortedEditorsFromPlugins.add(editor);
194
195         // add it to the table of mappings
196
Iterator JavaDoc itr = extensions.iterator();
197         while (itr.hasNext()) {
198             String JavaDoc fileExtension = (String JavaDoc) itr.next();
199
200             if (fileExtension != null && fileExtension.length() > 0) {
201                 FileEditorMapping mapping = getMappingFor("*." + fileExtension); //$NON-NLS-1$
202
if (mapping == null) { // no mapping for that extension
203
mapping = new FileEditorMapping(fileExtension);
204                     typeEditorMappings.putDefault(mappingKeyFor(mapping),
205                             mapping);
206                 }
207                 mapping.addEditor(editor);
208                 if (bDefault) {
209                     mapping.setDefaultEditor(editor);
210                 }
211             }
212         }
213
214         // add it to the table of mappings
215
itr = filenames.iterator();
216         while (itr.hasNext()) {
217             String JavaDoc filename = (String JavaDoc) itr.next();
218
219             if (filename != null && filename.length() > 0) {
220                 FileEditorMapping mapping = getMappingFor(filename);
221                 if (mapping == null) { // no mapping for that extension
222
String JavaDoc name;
223                     String JavaDoc extension;
224                     int index = filename.indexOf('.');
225                     if (index < 0) {
226                         name = filename;
227                         extension = ""; //$NON-NLS-1$
228
} else {
229                         name = filename.substring(0, index);
230                         extension = filename.substring(index + 1);
231                     }
232                     mapping = new FileEditorMapping(name, extension);
233                     typeEditorMappings.putDefault(mappingKeyFor(mapping),
234                             mapping);
235                 }
236                 mapping.addEditor(editor);
237                 if (bDefault) {
238                     mapping.setDefaultEditor(editor);
239                 }
240             }
241         }
242         
243         
244         itr = contentTypeVector.iterator();
245         while(itr.hasNext()) {
246             String JavaDoc contentTypeId = (String JavaDoc) itr.next();
247             if (contentTypeId != null && contentTypeId.length() > 0) {
248                 IContentType contentType = Platform.getContentTypeManager().getContentType(contentTypeId);
249                 if (contentType != null) {
250                     IEditorDescriptor [] editorArray = (IEditorDescriptor[]) contentTypeToEditorMappings.get(contentType);
251                     if (editorArray == null) {
252                         editorArray = new IEditorDescriptor[] {editor};
253                         contentTypeToEditorMappings.put(contentType, editorArray);
254                     }
255                     else {
256                         IEditorDescriptor [] newArray = new IEditorDescriptor[editorArray.length + 1];
257                         if (bDefault) { // default editors go to the front of the line
258
newArray[0] = editor;
259                             System.arraycopy(editorArray, 0, newArray, 1, editorArray.length);
260                         }
261                         else {
262                             newArray[editorArray.length] = editor;
263                             System.arraycopy(editorArray, 0, newArray, 0, editorArray.length);
264                         }
265                         contentTypeToEditorMappings.put(contentType, newArray);
266                     }
267                 }
268             }
269         }
270
271         // Update editor map.
272
mapIDtoEditor.put(editor.getId(), editor);
273     }
274
275     /**
276      * Add external editors to the editor mapping.
277      */

278     private void addExternalEditorsToEditorMap() {
279         IEditorDescriptor desc = null;
280
281         // Add registered editors (may include external editors).
282
FileEditorMapping maps[] = typeEditorMappings.allMappings();
283         for (int i = 0; i < maps.length; i++) {
284             FileEditorMapping map = maps[i];
285             IEditorDescriptor[] descArray = map.getEditors();
286             for (int n = 0; n < descArray.length; n++) {
287                 desc = descArray[n];
288                 mapIDtoEditor.put(desc.getId(), desc);
289             }
290         }
291     }
292
293     /*
294      * (non-Javadoc) Method declared on IEditorRegistry.
295      */

296     public void addPropertyListener(IPropertyListener l) {
297         addListenerObject(l);
298     }
299
300     /*
301      * (non-Javadoc) Method declared on IEditorRegistry.
302      */

303     public IEditorDescriptor findEditor(String JavaDoc id) {
304         return (IEditorDescriptor) mapIDtoEditor.get(id);
305     }
306
307     /**
308      * Fires a property changed event to all registered listeners.
309      *
310      * @param type the type of event
311      * @see IEditorRegistry#PROP_CONTENTS
312      */

313     private void firePropertyChange(final int type) {
314         Object JavaDoc[] array = getListeners();
315         for (int nX = 0; nX < array.length; nX++) {
316             final IPropertyListener l = (IPropertyListener) array[nX];
317             Platform.run(new SafeRunnable() {
318                 public void run() {
319                     l.propertyChanged(EditorRegistry.this, type);
320                 }
321             });
322         }
323     }
324
325     /*
326      * (non-Javadoc) Method declared on IEditorRegistry.
327      *
328      * @deprecated
329      */

330     public IEditorDescriptor getDefaultEditor() {
331         // the default editor will always be the system external editor
332
// this should never return null
333
return findEditor(IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID);
334     }
335
336     /*
337      * (non-Javadoc) Method declared on IEditorRegistry.
338      */

339     public IEditorDescriptor getDefaultEditor(String JavaDoc filename) {
340         return getDefaultEditor(filename, guessAtContentType(filename));
341     }
342
343     /**
344      * Return the (approximated) content type for a file with the given name.
345      *
346      * @param filename the filename
347      * @return the content type or <code>null</code> if it could not be determined
348      * @since 3.1
349      */

350     private IContentType guessAtContentType(String JavaDoc filename) {
351         return Platform.getContentTypeManager().findContentTypeFor(filename);
352     }
353
354     /**
355      * Returns the default file image descriptor.
356      *
357      * @return the image descriptor
358      */

359     private ImageDescriptor getDefaultImage() {
360         // @issue what should be the default image?
361
return WorkbenchImages.getImageDescriptor(ISharedImages.IMG_OBJ_FILE);
362     }
363
364     /*
365      * (non-Javadoc) Method declared on IEditorRegistry.
366      */

367     public IEditorDescriptor[] getEditors(String JavaDoc filename) {
368         return getEditors(filename, guessAtContentType(filename));
369     }
370
371     /*
372      * (non-Javadoc) Method declared on IEditorRegistry.
373      */

374     public IFileEditorMapping[] getFileEditorMappings() {
375         FileEditorMapping[] array = typeEditorMappings.allMappings();
376         final Collator collator = Collator.getInstance();
377         Arrays.sort(array, new Comparator JavaDoc() {
378             
379             /* (non-Javadoc)
380              * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
381              */

382             public int compare(Object JavaDoc o1, Object JavaDoc o2) {
383                 String JavaDoc s1 = ((FileEditorMapping) o1).getLabel();
384                 String JavaDoc s2 = ((FileEditorMapping) o2).getLabel();
385                 return collator.compare(s1, s2);
386             }
387         });
388         return array;
389     }
390
391     /*
392      * (non-Javadoc) Method declared on IEditorRegistry.
393      */

394     public ImageDescriptor getImageDescriptor(String JavaDoc filename) {
395         return getImageDescriptor(filename, guessAtContentType(filename));
396     }
397
398     /**
399      * Find the file editor mapping for the file extension. Returns
400      * <code>null</code> if not found.
401      *
402      * @param ext
403      * the file extension
404      * @return the mapping, or <code>null</code>
405      */

406     private FileEditorMapping getMappingFor(String JavaDoc ext) {
407         if (ext == null) {
408             return null;
409         }
410         String JavaDoc key = mappingKeyFor(ext);
411         return typeEditorMappings.get(key);
412     }
413
414     /**
415      * Find the file editor mappings for the given filename.
416      * <p>
417      * Return an array of two FileEditorMapping items, where the first mapping
418      * is for the entire filename, and the second mapping is for the filename's
419      * extension only. These items can be null if no mapping exist on the
420      * filename and/or filename's extension.</p>
421      *
422      * @param filename the filename
423      * @return the mappings
424      */

425     private FileEditorMapping[] getMappingForFilename(String JavaDoc filename) {
426         FileEditorMapping[] mapping = new FileEditorMapping[2];
427
428         // Lookup on entire filename
429
mapping[0] = getMappingFor(filename);
430
431         // Lookup on filename's extension
432
int index = filename.lastIndexOf('.');
433         if (index > -1) {
434             String JavaDoc extension = filename.substring(index);
435             mapping[1] = getMappingFor("*" + extension); //$NON-NLS-1$
436
}
437
438         return mapping;
439     }
440
441     /**
442      * Return the editor descriptors pulled from the OS.
443      * <p>
444      * WARNING! The image described by each editor descriptor is *not* known by
445      * the workbench's graphic registry. Therefore clients must take care to
446      * ensure that if they access any of the images held by these editors that
447      * they also dispose them
448      * </p>
449      * @return the editor descriptors
450      */

451     public IEditorDescriptor[] getSortedEditorsFromOS() {
452         List JavaDoc externalEditors = new ArrayList JavaDoc();
453         Program[] programs = Program.getPrograms();
454
455         for (int i = 0; i < programs.length; i++) {
456             //1FPLRL2: ITPUI:WINNT - NOTEPAD editor cannot be launched
457
//Some entries start with %SystemRoot%
458
//For such cases just use the file name as they are generally
459
//in directories which are on the path
460
/*
461              * if (fileName.charAt(0) == '%') { fileName = name + ".exe"; }
462              */

463
464             EditorDescriptor editor = new EditorDescriptor();
465             editor.setOpenMode(EditorDescriptor.OPEN_EXTERNAL);
466             editor.setProgram(programs[i]);
467
468             // determine the program icon this editor would need (do not let it
469
// be cached in the workbench registry)
470
ImageDescriptor desc = new ExternalProgramImageDescriptor(
471                     programs[i]);
472             editor.setImageDescriptor(desc);
473             externalEditors.add(editor);
474         }
475
476         Object JavaDoc[] tempArray = sortEditors(externalEditors);
477         IEditorDescriptor[] array = new IEditorDescriptor[externalEditors
478                 .size()];
479         for (int i = 0; i < tempArray.length; i++) {
480             array[i] = (IEditorDescriptor) tempArray[i];
481         }
482         return array;
483     }
484
485     /**
486      * Return the editors loaded from plugins.
487      *
488      * @return the sorted array of editors declared in plugins
489      * @see #comparer
490      */

491     public IEditorDescriptor[] getSortedEditorsFromPlugins() {
492         IEditorDescriptor[] array = new IEditorDescriptor[sortedEditorsFromPlugins
493                 .size()];
494         sortedEditorsFromPlugins.toArray(array);
495         return array;
496     }
497
498     /**
499      * Answer an intial id to editor map. This will create a new map and
500      * populate it with the default system editors.
501      *
502      * @param initialSize
503      * the initial size of the map
504      * @return the new map
505      */

506     private HashMap JavaDoc initialIdToEditorMap(int initialSize) {
507         HashMap JavaDoc map = new HashMap JavaDoc(initialSize);
508         addSystemEditors(map);
509         return map;
510     }
511
512     /**
513      * Add the system editors to the provided map. This will always add an
514      * editor with an id of {@link #SYSTEM_EXTERNAL_EDITOR_ID} and may also add
515      * an editor with id of {@link #SYSTEM_INPLACE_EDITOR_ID} if the system
516      * configuration supports it.
517      *
518      * @param map the map to augment
519      */

520     private void addSystemEditors(HashMap JavaDoc map) {
521         // there will always be a system external editor descriptor
522
EditorDescriptor editor = new EditorDescriptor();
523         editor.setID(IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID);
524         editor.setName(WorkbenchMessages.SystemEditorDescription_name);
525         editor.setOpenMode(EditorDescriptor.OPEN_EXTERNAL);
526         // @issue we need a real icon for this editor?
527
map.put(IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID, editor);
528
529         // there may be a system in-place editor if supported by platform
530
if (ComponentSupport.inPlaceEditorSupported()) {
531             editor = new EditorDescriptor();
532             editor.setID(IEditorRegistry.SYSTEM_INPLACE_EDITOR_ID);
533             editor.setName(WorkbenchMessages.SystemInPlaceDescription_name);
534             editor.setOpenMode(EditorDescriptor.OPEN_INPLACE);
535             // @issue we need a real icon for this editor?
536
map.put(IEditorRegistry.SYSTEM_INPLACE_EDITOR_ID, editor);
537         }
538         
539         EditorDescriptor emptyEditorDescriptor = new EditorDescriptor();
540         emptyEditorDescriptor.setID(EMPTY_EDITOR_ID);
541         emptyEditorDescriptor.setName("(Empty)"); //$NON-NLS-1$
542
emptyEditorDescriptor
543                 .setImageDescriptor(WorkbenchImages
544                         .getImageDescriptor(IWorkbenchGraphicConstants.IMG_OBJ_ELEMENT));
545         map.put(EMPTY_EDITOR_ID, emptyEditorDescriptor);
546     }
547
548     /**
549      * Initialize the registry state from plugin declarations and preference
550      * overrides.
551      */

552     private void initializeFromStorage() {
553         typeEditorMappings = new EditorMap();
554         extensionImages = new HashMap JavaDoc();
555
556         //Get editors from the registry
557
EditorRegistryReader registryReader = new EditorRegistryReader();
558         registryReader.addEditors(this);
559         sortInternalEditors();
560         rebuildInternalEditorMap();
561
562         IPreferenceStore store = PlatformUI.getPreferenceStore();
563         String JavaDoc defaultEditors = store
564                 .getString(IPreferenceConstants.DEFAULT_EDITORS);
565         String JavaDoc chachedDefaultEditors = store
566                 .getString(IPreferenceConstants.DEFAULT_EDITORS_CACHE);
567
568         //If defaults has changed load it afterwards so it overrides the users
569
// associations.
570
if (defaultEditors == null
571                 || defaultEditors.equals(chachedDefaultEditors)) {
572             setProductDefaults(defaultEditors);
573             loadAssociations(); //get saved earlier state
574
} else {
575             loadAssociations(); //get saved earlier state
576
setProductDefaults(defaultEditors);
577             store.putValue(IPreferenceConstants.DEFAULT_EDITORS_CACHE,
578                     defaultEditors);
579         }
580         addExternalEditorsToEditorMap();
581     }
582
583     /**
584      * Set the default editors according to the preference store which can be
585      * overwritten in the file properties.ini. In the form:
586      * <p>
587      * <code>ext1:id1;ext2:id2;...</code>
588      * </p>
589      *
590      * @param defaultEditors the default editors to set
591      */

592     private void setProductDefaults(String JavaDoc defaultEditors) {
593         if (defaultEditors == null || defaultEditors.length() == 0) {
594             return;
595         }
596
597         StringTokenizer JavaDoc extEditors = new StringTokenizer JavaDoc(defaultEditors,
598                 new Character JavaDoc(IPreferenceConstants.SEPARATOR).toString());
599         while (extEditors.hasMoreTokens()) {
600             String JavaDoc extEditor = extEditors.nextToken().trim();
601             int index = extEditor.indexOf(':');
602             if (extEditor.length() < 3 || index <= 0
603                     || index >= (extEditor.length() - 1)) {
604                 //Extension and id must have at least one char.
605
WorkbenchPlugin
606                         .log("Error setting default editor. Could not parse '" + extEditor + "'. Default editors should be specified as '*.ext1:editorId1;*.ext2:editorId2'"); //$NON-NLS-1$ //$NON-NLS-2$
607
return;
608             }
609             String JavaDoc ext = extEditor.substring(0, index).trim();
610             String JavaDoc editorId = extEditor.substring(index + 1).trim();
611             FileEditorMapping mapping = getMappingFor(ext);
612             if (mapping == null) {
613                 WorkbenchPlugin
614                         .log("Error setting default editor. Could not find mapping for '" + ext + "'."); //$NON-NLS-1$ //$NON-NLS-2$
615
continue;
616             }
617             EditorDescriptor editor = (EditorDescriptor) findEditor(editorId);
618             if (editor == null) {
619                 WorkbenchPlugin
620                         .log("Error setting default editor. Could not find editor: '" + editorId + "'."); //$NON-NLS-1$ //$NON-NLS-2$
621
continue;
622             }
623             mapping.setDefaultEditor(editor);
624         }
625     }
626
627     /**
628      * Read the editors defined in the preferences store.
629      *
630      * @param editorTable
631      * Editor table to store the editor definitions.
632      * @return true if the table is built succesfully.
633      */

634     private boolean readEditors(Map JavaDoc editorTable) {
635         //Get the workbench plugin's working directory
636
IPath workbenchStatePath = WorkbenchPlugin.getDefault().getDataLocation();
637         if(workbenchStatePath == null) {
638             return false;
639         }
640         IPreferenceStore store = WorkbenchPlugin.getDefault()
641                 .getPreferenceStore();
642         Reader JavaDoc reader = null;
643         try {
644             // Get the editors defined in the preferences store
645
String JavaDoc xmlString = store.getString(IPreferenceConstants.EDITORS);
646             if (xmlString == null || xmlString.length() == 0) {
647                 FileInputStream JavaDoc stream = new FileInputStream JavaDoc(workbenchStatePath
648                         .append(IWorkbenchConstants.EDITOR_FILE_NAME)
649                         .toOSString());
650                 reader = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(stream,
651                         "utf-8")); //$NON-NLS-1$
652
} else {
653                 reader = new StringReader JavaDoc(xmlString);
654             }
655             XMLMemento memento = XMLMemento.createReadRoot(reader);
656             EditorDescriptor editor;
657             IMemento[] edMementos = memento
658                     .getChildren(IWorkbenchConstants.TAG_DESCRIPTOR);
659             // Get the editors and validate each one
660
for (int i = 0; i < edMementos.length; i++) {
661                 editor = new EditorDescriptor();
662                 boolean valid = editor.loadValues(edMementos[i]);
663                 if (!valid) {
664                     continue;
665                 }
666                 if (editor.getPluginID() != null) {
667                     //If the editor is from a plugin we use its ID to look it
668
// up in the mapping of editors we
669
//have obtained from plugins. This allows us to verify that
670
// the editor is still valid
671
//and allows us to get the editor description from the
672
// mapping table which has
673
//a valid config element field.
674
EditorDescriptor validEditorDescritor = (EditorDescriptor) mapIDtoEditor
675                             .get(editor.getId());
676                     if (validEditorDescritor != null) {
677                         editorTable.put(validEditorDescritor.getId(),
678                                 validEditorDescritor);
679                     }
680                 } else { //This is either from a program or a user defined
681
// editor
682
ImageDescriptor descriptor;
683                     if (editor.getProgram() == null) {
684                         descriptor = new ProgramImageDescriptor(editor
685                                 .getFileName(), 0);
686                     } else {
687                         descriptor = new ExternalProgramImageDescriptor(editor
688                                 .getProgram());
689                     }
690                     editor.setImageDescriptor(descriptor);
691                     editorTable.put(editor.getId(), editor);
692                 }
693             }
694         } catch (IOException JavaDoc e) {
695             try {
696                 if (reader != null) {
697                     reader.close();
698                 }
699             } catch (IOException JavaDoc ex) {
700                 e.printStackTrace();
701             }
702             //Ignore this as the workbench may not yet have saved any state
703
return false;
704         } catch (WorkbenchException e) {
705             ErrorDialog.openError((Shell) null, WorkbenchMessages.EditorRegistry_errorTitle,
706                     WorkbenchMessages.EditorRegistry_errorMessage,
707                     e.getStatus());
708             return false;
709         }
710
711         return true;
712     }
713
714     /**
715      * Read the file types and associate them to their defined editor(s).
716      *
717      * @param editorTable
718      * The editor table containing the defined editors.
719      * @param reader
720      * Reader containing the preferences content for the resources.
721      *
722      * @throws WorkbenchException
723      */

724     public void readResources(Map JavaDoc editorTable, Reader JavaDoc reader)
725             throws WorkbenchException {
726         XMLMemento memento = XMLMemento.createReadRoot(reader);
727         String JavaDoc versionString = memento.getString(IWorkbenchConstants.TAG_VERSION);
728         boolean versionIs31 = "3.1".equals(versionString); //$NON-NLS-1$
729

730         IMemento[] extMementos = memento
731                 .getChildren(IWorkbenchConstants.TAG_INFO);
732         for (int i = 0; i < extMementos.length; i++) {
733             String JavaDoc name = extMementos[i]
734                     .getString(IWorkbenchConstants.TAG_NAME);
735             if (name == null) {
736                 name = "*"; //$NON-NLS-1$
737
}
738             String JavaDoc extension = extMementos[i]
739                     .getString(IWorkbenchConstants.TAG_EXTENSION);
740             IMemento[] idMementos = extMementos[i]
741                     .getChildren(IWorkbenchConstants.TAG_EDITOR);
742             String JavaDoc[] editorIDs = new String JavaDoc[idMementos.length];
743             for (int j = 0; j < idMementos.length; j++) {
744                 editorIDs[j] = idMementos[j]
745                         .getString(IWorkbenchConstants.TAG_ID);
746             }
747             idMementos = extMementos[i]
748                     .getChildren(IWorkbenchConstants.TAG_DELETED_EDITOR);
749             String JavaDoc[] deletedEditorIDs = new String JavaDoc[idMementos.length];
750             for (int j = 0; j < idMementos.length; j++) {
751                 deletedEditorIDs[j] = idMementos[j]
752                         .getString(IWorkbenchConstants.TAG_ID);
753             }
754             FileEditorMapping mapping = getMappingFor(name + "." + extension); //$NON-NLS-1$
755
if (mapping == null) {
756                 mapping = new FileEditorMapping(name, extension);
757             }
758             List JavaDoc editors = new ArrayList JavaDoc();
759             for (int j = 0; j < editorIDs.length; j++) {
760                 if (editorIDs[j] != null) {
761                     EditorDescriptor editor = (EditorDescriptor) editorTable
762                             .get(editorIDs[j]);
763                     if (editor != null) {
764                         editors.add(editor);
765                     }
766                 }
767             }
768             List JavaDoc deletedEditors = new ArrayList JavaDoc();
769             for (int j = 0; j < deletedEditorIDs.length; j++) {
770                 if (deletedEditorIDs[j] != null) {
771                     EditorDescriptor editor = (EditorDescriptor) editorTable
772                             .get(deletedEditorIDs[j]);
773                     if (editor != null) {
774                         deletedEditors.add(editor);
775                     }
776                 }
777             }
778             
779             List JavaDoc defaultEditors = new ArrayList JavaDoc();
780             
781             if (versionIs31) { // parse the new format
782
idMementos = extMementos[i]
783                         .getChildren(IWorkbenchConstants.TAG_DEFAULT_EDITOR);
784                 String JavaDoc[] defaultEditorIds = new String JavaDoc[idMementos.length];
785                 for (int j = 0; j < idMementos.length; j++) {
786                     defaultEditorIds[j] = idMementos[j]
787                             .getString(IWorkbenchConstants.TAG_ID);
788                 }
789                 for (int j = 0; j < defaultEditorIds.length; j++) {
790                     if (defaultEditorIds[j] != null) {
791                         EditorDescriptor editor = (EditorDescriptor) editorTable
792                                 .get(defaultEditorIds[j]);
793                         if (editor != null) {
794                             defaultEditors.add(editor);
795                         }
796                     }
797                 }
798             }
799             else { // guess at pre 3.1 format defaults
800
if (!editors.isEmpty()) {
801                         EditorDescriptor editor = (EditorDescriptor) editors.get(0);
802                         if (editor != null) {
803                             defaultEditors.add(editor);
804                         }
805                     }
806                     defaultEditors.addAll(Arrays.asList(mapping.getDeclaredDefaultEditors()));
807             }
808             
809             // Add any new editors that have already been read from the registry
810
// which were not deleted.
811
IEditorDescriptor[] editorsArray = mapping.getEditors();
812             for (int j = 0; j < editorsArray.length; j++) {
813                 if (!contains(editors, editorsArray[j])
814                         && !deletedEditors.contains(editorsArray[j])) {
815                     editors.add(editorsArray[j]);
816                 }
817             }
818             // Map the editor(s) to the file type
819
mapping.setEditorsList(editors);
820             mapping.setDeletedEditorsList(deletedEditors);
821             mapping.setDefaultEditors(defaultEditors);
822             typeEditorMappings.put(mappingKeyFor(mapping), mapping);
823         }
824     }
825
826     /**
827      * Determine if the editors list contains the editor descriptor.
828      *
829      * @param editorsArray
830      * The list of editors
831      * @param editorDescriptor
832      * The editor descriptor
833      * @return <code>true</code> if the editors list contains the editor descriptor
834      */

835     private boolean contains(List JavaDoc editorsArray,
836             IEditorDescriptor editorDescriptor) {
837         IEditorDescriptor currentEditorDescriptor = null;
838         Iterator JavaDoc i = editorsArray.iterator();
839         while (i.hasNext()) {
840             currentEditorDescriptor = (IEditorDescriptor) i.next();
841             if (currentEditorDescriptor.getId()
842                     .equals(editorDescriptor.getId())) {
843                 return true;
844             }
845         }
846         return false;
847
848     }
849
850     /**
851      * Creates the reader for the resources preferences defined in the
852      * preference store.
853      *
854      * @param editorTable
855      * The editor table containing the defined editors.
856      * @return true if the resources are read succesfully.
857      */

858     private boolean readResources(Map JavaDoc editorTable) {
859         //Get the workbench plugin's working directory
860
IPath workbenchStatePath = WorkbenchPlugin.getDefault().getDataLocation();
861         // XXX: nobody cares about this return value
862
if(workbenchStatePath == null) {
863             return false;
864         }
865         IPreferenceStore store = WorkbenchPlugin.getDefault()
866                 .getPreferenceStore();
867         Reader JavaDoc reader = null;
868         try {
869             // Get the resource types
870
String JavaDoc xmlString = store.getString(IPreferenceConstants.RESOURCES);
871             if (xmlString == null || xmlString.length() == 0) {
872                 FileInputStream JavaDoc stream = new FileInputStream JavaDoc(workbenchStatePath
873                         .append(IWorkbenchConstants.RESOURCE_TYPE_FILE_NAME)
874                         .toOSString());
875                 reader = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(stream,
876                         "utf-8")); //$NON-NLS-1$
877
} else {
878                 reader = new StringReader JavaDoc(xmlString);
879             }
880             // Read the defined resources into the table
881
readResources(editorTable, reader);
882         } catch (IOException JavaDoc e) {
883             try {
884                 if (reader != null) {
885                     reader.close();
886                 }
887             } catch (IOException JavaDoc ex) {
888                 ex.printStackTrace();
889             }
890             MessageDialog.openError((Shell) null, WorkbenchMessages.EditorRegistry_errorTitle,
891                     WorkbenchMessages.EditorRegistry_errorMessage);
892             return false;
893         } catch (WorkbenchException e) {
894             ErrorDialog.openError((Shell) null, WorkbenchMessages.EditorRegistry_errorTitle,
895                     WorkbenchMessages.EditorRegistry_errorMessage,
896                     e.getStatus());
897             return false;
898         }
899         return true;
900
901     }
902
903     /**
904      * Load the serialized resource associations Return true if the operation
905      * was successful, false otherwise
906      */

907     private boolean loadAssociations() {
908         Map JavaDoc editorTable = new HashMap JavaDoc();
909         if (!readEditors(editorTable)) {
910             return false;
911         }
912         return readResources(editorTable);
913     }
914
915     /**
916      * Return a friendly version of the given key suitable for use in the editor
917      * map.
918      */

919     private String JavaDoc mappingKeyFor(String JavaDoc type) {
920         // keep everyting lower case for case-sensitive platforms
921
return type.toLowerCase();
922     }
923
924     /**
925      * Return a key that combines the file's name and extension of the given
926      * mapping
927      *
928      * @param mapping the mapping to generate a key for
929      */

930     private String JavaDoc mappingKeyFor(FileEditorMapping mapping) {
931         return mappingKeyFor(mapping.getName()
932                 + (mapping.getExtension().length() == 0 ? "" : "." + mapping.getExtension())); //$NON-NLS-1$ //$NON-NLS-2$
933
}
934
935     /**
936      * Rebuild the editor map
937      */

938     private void rebuildEditorMap() {
939         rebuildInternalEditorMap();
940         addExternalEditorsToEditorMap();
941     }
942
943     /**
944      * Rebuild the internal editor mapping.
945      */

946     private void rebuildInternalEditorMap() {
947         Iterator JavaDoc itr = null;
948         IEditorDescriptor desc = null;
949
950         // Allocate a new map.
951
mapIDtoEditor = initialIdToEditorMap(mapIDtoEditor.size());
952
953         // Add plugin editors.
954
itr = sortedEditorsFromPlugins.iterator();
955         while (itr.hasNext()) {
956             desc = (IEditorDescriptor) itr.next();
957             mapIDtoEditor.put(desc.getId(), desc);
958         }
959     }
960
961     /*
962      * (non-Javadoc) Method declared on IEditorRegistry.
963      */

964     public void removePropertyListener(IPropertyListener l) {
965         removeListenerObject(l);
966     }
967
968     /**
969      * Save the registry to the filesystem by serializing the current resource
970      * associations.
971      */

972     public void saveAssociations() {
973         //Save the resource type descriptions
974
List JavaDoc editors = new ArrayList JavaDoc();
975         IPreferenceStore store = WorkbenchPlugin.getDefault()
976                 .getPreferenceStore();
977
978         XMLMemento memento = XMLMemento
979                 .createWriteRoot(IWorkbenchConstants.TAG_EDITORS);
980         memento.putString(IWorkbenchConstants.TAG_VERSION, "3.1"); //$NON-NLS-1$
981
FileEditorMapping maps[] = typeEditorMappings.userMappings();
982         for (int mapsIndex = 0; mapsIndex < maps.length; mapsIndex++) {
983             FileEditorMapping type = maps[mapsIndex];
984             IMemento editorMemento = memento
985                     .createChild(IWorkbenchConstants.TAG_INFO);
986             editorMemento.putString(IWorkbenchConstants.TAG_NAME, type
987                     .getName());
988             editorMemento.putString(IWorkbenchConstants.TAG_EXTENSION, type
989                     .getExtension());
990             IEditorDescriptor[] editorArray = type.getEditors();
991             for (int i = 0; i < editorArray.length; i++) {
992                 EditorDescriptor editor = (EditorDescriptor) editorArray[i];
993                 if (!editors.contains(editor)) {
994                     editors.add(editor);
995                 }
996                 IMemento idMemento = editorMemento
997                         .createChild(IWorkbenchConstants.TAG_EDITOR);
998                 idMemento.putString(IWorkbenchConstants.TAG_ID, editorArray[i]
999                         .getId());
1000            }
1001            editorArray = type.getDeletedEditors();
1002            for (int i = 0; i < editorArray.length; i++) {
1003                EditorDescriptor editor = (EditorDescriptor) editorArray[i];
1004                if (!editors.contains(editor)) {
1005                    editors.add(editor);
1006                }
1007                IMemento idMemento = editorMemento
1008                        .createChild(IWorkbenchConstants.TAG_DELETED_EDITOR);
1009                idMemento.putString(IWorkbenchConstants.TAG_ID, editorArray[i]
1010                        .getId());
1011            }
1012            editorArray = type.getDeclaredDefaultEditors();
1013            for (int i = 0; i < editorArray.length; i++) {
1014                EditorDescriptor editor = (EditorDescriptor) editorArray[i];
1015                if (!editors.contains(editor)) {
1016                    editors.add(editor);
1017                }
1018                IMemento idMemento = editorMemento
1019                        .createChild(IWorkbenchConstants.TAG_DEFAULT_EDITOR);
1020                idMemento.putString(IWorkbenchConstants.TAG_ID, editorArray[i]
1021                        .getId());
1022            }
1023        }
1024        Writer JavaDoc writer = null;
1025        try {
1026            writer = new StringWriter JavaDoc();
1027            memento.save(writer);
1028            writer.close();
1029            store.setValue(IPreferenceConstants.RESOURCES, writer.toString());
1030        } catch (IOException JavaDoc e) {
1031            try {
1032                if (writer != null) {
1033                    writer.close();
1034                }
1035            } catch (IOException JavaDoc ex) {
1036                ex.printStackTrace();
1037            }
1038            MessageDialog.openError((Shell) null, "Saving Problems", //$NON-NLS-1$
1039
"Unable to save resource associations."); //$NON-NLS-1$
1040
return;
1041        }
1042
1043        memento = XMLMemento.createWriteRoot(IWorkbenchConstants.TAG_EDITORS);
1044        Iterator JavaDoc itr = editors.iterator();
1045        while (itr.hasNext()) {
1046            EditorDescriptor editor = (EditorDescriptor) itr.next();
1047            IMemento editorMemento = memento
1048                    .createChild(IWorkbenchConstants.TAG_DESCRIPTOR);
1049            editor.saveValues(editorMemento);
1050        }
1051        writer = null;
1052        try {
1053            writer = new StringWriter JavaDoc();
1054            memento.save(writer);
1055            writer.close();
1056            store.setValue(IPreferenceConstants.EDITORS, writer.toString());
1057        } catch (IOException JavaDoc e) {
1058            try {
1059                if (writer != null) {
1060                    writer.close();
1061                }
1062            } catch (IOException JavaDoc ex) {
1063                ex.printStackTrace();
1064            }
1065            MessageDialog.openError((Shell) null,
1066                    "Error", "Unable to save resource associations."); //$NON-NLS-1$ //$NON-NLS-2$
1067
return;
1068        }
1069    }
1070
1071    /**
1072     * Set the collection of FileEditorMappings. The given collection is
1073     * converted into the internal hash table for faster lookup Each mapping
1074     * goes from an extension to the collection of editors that work on it. This
1075     * operation will rebuild the internal editor mappings.
1076     *
1077     * @param newResourceTypes
1078     * te new file editor mappings.
1079     */

1080    public void setFileEditorMappings(FileEditorMapping[] newResourceTypes) {
1081        typeEditorMappings = new EditorMap();
1082        for (int i = 0; i < newResourceTypes.length; i++) {
1083            FileEditorMapping mapping = newResourceTypes[i];
1084            typeEditorMappings.put(mappingKeyFor(mapping), mapping);
1085        }
1086        extensionImages = new HashMap JavaDoc();
1087        rebuildEditorMap();
1088        firePropertyChange(PROP_CONTENTS);
1089    }
1090
1091    /*
1092     * (non-Javadoc) Method declared on IEditorRegistry.
1093     */

1094    public void setDefaultEditor(String JavaDoc fileName, String JavaDoc editorId) {
1095        EditorDescriptor desc = (EditorDescriptor) findEditor(editorId);
1096        FileEditorMapping[] mapping = getMappingForFilename(fileName);
1097        if (mapping[0] != null) {
1098            mapping[0].setDefaultEditor(desc);
1099        }
1100        if (mapping[1] != null) {
1101            mapping[1].setDefaultEditor(desc);
1102        }
1103    }
1104
1105    /**
1106     * Alphabetically sort the internal editors.
1107     *
1108     * @see #comparer
1109     */

1110    private Object JavaDoc[] sortEditors(List JavaDoc unsortedList) {
1111        Object JavaDoc[] array = new Object JavaDoc[unsortedList.size()];
1112        unsortedList.toArray(array);
1113
1114        Collections.sort(Arrays.asList(array), comparer);
1115        return array;
1116    }
1117
1118    /**
1119     * Alphabetically sort the internal editors.
1120     *
1121     * @see #comparer
1122     */

1123    private void sortInternalEditors() {
1124        Object JavaDoc[] array = sortEditors(sortedEditorsFromPlugins);
1125        sortedEditorsFromPlugins = new ArrayList JavaDoc();
1126        for (int i = 0; i < array.length; i++) {
1127            sortedEditorsFromPlugins.add(array[i]);
1128        }
1129    }
1130
1131    /**
1132     * Map of FileEditorMapping (extension to FileEditorMapping) Uses two
1133     * java.util.HashMap: one keeps the default which are set by the plugins and
1134     * the other keeps the changes made by the user through the preference page.
1135     */

1136    private static class EditorMap {
1137        HashMap JavaDoc defaultMap = new HashMap JavaDoc();
1138
1139        HashMap JavaDoc map = new HashMap JavaDoc();
1140
1141        /**
1142         * Put a default mapping into the editor map.
1143         *
1144         * @param key the key to set
1145         * @param value the value to associate
1146         */

1147        public void putDefault(String JavaDoc key, FileEditorMapping value) {
1148            defaultMap.put(key, value);
1149        }
1150
1151        /**
1152         * Put a mapping into the user editor map.
1153         *
1154         * @param key the key to set
1155         * @param value the value to associate
1156         */

1157        public void put(String JavaDoc key, FileEditorMapping value) {
1158            Object JavaDoc result = defaultMap.get(key);
1159            if (value.equals(result)) {
1160                map.remove(key);
1161            } else {
1162                map.put(key, value);
1163            }
1164        }
1165
1166        /**
1167         * Return the mapping associated to the key. First searches user
1168         * map, and then falls back to the default map if there is no match. May
1169         * return <code>null</code>
1170         *
1171         * @param key
1172         * the key to search for
1173         * @return the mapping associated to the key or <code>null</code>
1174         */

1175        public FileEditorMapping get(String JavaDoc key) {
1176            Object JavaDoc result = map.get(key);
1177            if (result == null) {
1178                result = defaultMap.get(key);
1179            }
1180            return (FileEditorMapping) result;
1181        }
1182
1183        /**
1184         * Return all mappings. This will return default mappings overlayed with
1185         * user mappings.
1186         *
1187         * @return the mappings
1188         */

1189        public FileEditorMapping[] allMappings() {
1190            HashMap JavaDoc merge = (HashMap JavaDoc) defaultMap.clone();
1191            merge.putAll(map);
1192            Collection JavaDoc values = merge.values();
1193            FileEditorMapping result[] = new FileEditorMapping[values.size()];
1194            return (FileEditorMapping[]) values.toArray(result);
1195        }
1196
1197        /**
1198         * Return all user mappings.
1199         *
1200         * @return the mappings
1201         */

1202        public FileEditorMapping[] userMappings() {
1203            Collection JavaDoc values = map.values();
1204            FileEditorMapping result[] = new FileEditorMapping[values.size()];
1205            return (FileEditorMapping[]) values.toArray(result);
1206        }
1207    }
1208
1209    /*
1210     * (non-Javadoc)
1211     *
1212     * @see org.eclipse.ui.IEditorRegistry#isSystemInPlaceEditorAvailable(String)
1213     */

1214    public boolean isSystemInPlaceEditorAvailable(String JavaDoc filename) {
1215        return ComponentSupport.inPlaceEditorAvailable(filename);
1216    }
1217
1218    /*
1219     * (non-Javadoc)
1220     *
1221     * @see org.eclipse.ui.IEditorRegistry#isSystemExternalEditorAvailable(String)
1222     */

1223    public boolean isSystemExternalEditorAvailable(String JavaDoc filename) {
1224        int nDot = filename.lastIndexOf('.');
1225        if (nDot >= 0) {
1226            String JavaDoc strName = filename.substring(nDot);
1227            return Program.findProgram(strName) != null;
1228        }
1229        return false;
1230    }
1231
1232    /*
1233     * (non-Javadoc)
1234     *
1235     * @see org.eclipse.ui.IEditorRegistry#getSystemExternalEditorImageDescriptor(java.lang.String)
1236     */

1237    public ImageDescriptor getSystemExternalEditorImageDescriptor(
1238            String JavaDoc filename) {
1239        Program externalProgram = null;
1240        int extensionIndex = filename.lastIndexOf('.');
1241        if (extensionIndex >= 0) {
1242            externalProgram = Program.findProgram(filename
1243                    .substring(extensionIndex));
1244        }
1245        if (externalProgram == null) {
1246            return null;
1247        }
1248        
1249        return new ExternalProgramImageDescriptor(externalProgram);
1250    }
1251    
1252    /**
1253     * Removes the entry with the value of the editor descriptor from the given
1254     * map. If the descriptor is the last descriptor in a given
1255     * FileEditorMapping then the mapping is removed from the map.
1256     *
1257     * @param map
1258     * the map to search
1259     * @param desc
1260     * the descriptor value to remove
1261     */

1262    private void removeEditorFromMapping(HashMap JavaDoc map, IEditorDescriptor desc) {
1263        Iterator JavaDoc iter = map.values().iterator();
1264        FileEditorMapping mapping;
1265        IEditorDescriptor[] editors;
1266        while (iter.hasNext()) {
1267            mapping = (FileEditorMapping) iter.next();
1268            editors = mapping.getEditors();
1269            for (int i = 0; i < editors.length; i++) {
1270                if (editors[i] == desc) {
1271                    mapping.removeEditor((EditorDescriptor) editors[i]);
1272                    break;
1273                }
1274            }
1275            if (editors.length <= 0) {
1276                map.remove(mapping);
1277                break;
1278            }
1279        }
1280    }
1281
1282    
1283    /* (non-Javadoc)
1284     * @see org.eclipse.core.runtime.dynamicHelpers.IExtensionChangeHandler#removeExtension(org.eclipse.core.runtime.IExtension, java.lang.Object[])
1285     */

1286    public void removeExtension(IExtension source, Object JavaDoc[] objects) {
1287        for (int i = 0; i < objects.length; i++) {
1288            if (objects[i] instanceof EditorDescriptor) {
1289                EditorDescriptor desc = (EditorDescriptor) objects[i];
1290
1291                sortedEditorsFromPlugins.remove(desc);
1292                mapIDtoEditor.values().remove(desc);
1293                removeEditorFromMapping(typeEditorMappings.defaultMap, desc);
1294                removeEditorFromMapping(typeEditorMappings.map, desc);
1295                //TODO remove from content type mappings
1296
}
1297
1298        }
1299    }
1300
1301    /* (non-Javadoc)
1302     * @see org.eclipse.core.runtime.dynamicHelpers.IExtensionChangeHandler#addExtension(org.eclipse.core.runtime.dynamicHelpers.IExtensionTracker, org.eclipse.core.runtime.IExtension)
1303     */

1304    public void addExtension(IExtensionTracker tracker, IExtension extension) {
1305        EditorRegistryReader eReader = new EditorRegistryReader();
1306        IConfigurationElement[] elements = extension.getConfigurationElements();
1307        for (int i = 0; i < elements.length; i++) {
1308            String JavaDoc id = elements[i].getAttribute(IWorkbenchConstants.TAG_ID);
1309            if (id != null && findEditor(id) != null) {
1310                continue;
1311            }
1312            eReader.readElement(this, elements[i]);
1313        }
1314    }
1315
1316    private IExtensionPoint getExtensionPointFilter() {
1317        return Platform.getExtensionRegistry().getExtensionPoint(PlatformUI.PLUGIN_ID, IWorkbenchRegistryConstants.PL_EDITOR);
1318    }
1319
1320    /* (non-Javadoc)
1321     * @see org.eclipse.ui.IEditorRegistry#getDefaultEditor(java.lang.String, org.eclipse.core.runtime.content.IContentType)
1322     */

1323    public IEditorDescriptor getDefaultEditor(String JavaDoc fileName, IContentType contentType) {
1324        return getEditorForContentType(fileName, contentType);
1325    }
1326
1327    /**
1328     * Return the editor for a file with a given content type.
1329     *
1330     * @param filename the file name
1331     * @param contentType the content type
1332     * @return the editor for a file with a given content type
1333     * @since 3.1
1334     */

1335    private IEditorDescriptor getEditorForContentType(String JavaDoc filename,
1336            IContentType contentType) {
1337        IEditorDescriptor desc = null;
1338        Object JavaDoc[] contentTypeResults = findRelatedObjects(contentType, filename, relatedRegistry);
1339        if (contentTypeResults != null && contentTypeResults.length > 0) {
1340            desc = (IEditorDescriptor) contentTypeResults[0];
1341        }
1342        return desc;
1343    }
1344
1345    /* (non-Javadoc)
1346     * @see org.eclipse.ui.IEditorRegistry#getEditors(java.lang.String, org.eclipse.core.runtime.content.IContentType)
1347     */

1348    public IEditorDescriptor[] getEditors(String JavaDoc fileName, IContentType contentType) {
1349        return findRelatedObjects(contentType, fileName, relatedRegistry);
1350    }
1351
1352    /* (non-Javadoc)
1353     * @see org.eclipse.ui.IEditorRegistry#getImageDescriptor(java.lang.String, org.eclipse.core.runtime.content.IContentType)
1354     */

1355    public ImageDescriptor getImageDescriptor(String JavaDoc filename, IContentType contentType) {
1356        if (filename == null) {
1357            return getDefaultImage();
1358        }
1359
1360        if (contentType != null) {
1361            IEditorDescriptor desc = getEditorForContentType(filename, contentType);
1362            if (desc != null) {
1363                ImageDescriptor anImage = (ImageDescriptor) extensionImages.get(desc);
1364                if (anImage != null) {
1365                    return anImage;
1366                }
1367                anImage = desc.getImageDescriptor();
1368                extensionImages.put(desc, anImage);
1369                return anImage;
1370            }
1371        }
1372        // Lookup in the cache first...
1373
String JavaDoc key = mappingKeyFor(filename);
1374        ImageDescriptor anImage = (ImageDescriptor) extensionImages.get(key);
1375        if (anImage != null) {
1376            return anImage;
1377        }
1378
1379        // See if we have a mapping for the filename or extension
1380
FileEditorMapping[] mapping = getMappingForFilename(filename);
1381        for (int i = 0; i < 2; i++) {
1382            if (mapping[i] != null) {
1383                // Lookup in the cache first...
1384
String JavaDoc mappingKey = mappingKeyFor(mapping[i]);
1385                ImageDescriptor mappingImage = (ImageDescriptor) extensionImages
1386                        .get(key);
1387                if (mappingImage != null) {
1388                    return mappingImage;
1389                }
1390                // Create it and cache it
1391
IEditorDescriptor editor = mapping[i].getDefaultEditor();
1392                if (editor != null) {
1393                    mappingImage = editor.getImageDescriptor();
1394                    extensionImages.put(mappingKey, mappingImage);
1395                    return mappingImage;
1396                }
1397            }
1398        }
1399
1400        // Nothing - time to look externally for the icon
1401
anImage = getSystemExternalEditorImageDescriptor(filename);
1402        if (anImage == null) {
1403            anImage = getDefaultImage();
1404        }
1405        // for dynamic UI - comment out the next line
1406
//extensionImages.put(key, anImage);
1407
return anImage;
1408
1409    }
1410    
1411    /**
1412     * Find objects related to the content type.
1413     *
1414     * This method is temporary and exists only to back us off of the
1415     * soon-to-be-removed IContentTypeManager.IRelatedRegistry API.
1416     *
1417     * @param type
1418     * @param fileName
1419     * @param registry
1420     * @return the related objects
1421     */

1422    private IEditorDescriptor [] findRelatedObjects(IContentType type, String JavaDoc fileName,
1423            RelatedRegistry registry) {
1424        List JavaDoc allRelated = new ArrayList JavaDoc();
1425        List JavaDoc nonDefaultFileEditors = new ArrayList JavaDoc();
1426        IEditorDescriptor [] related;
1427        
1428        if (fileName != null) {
1429            FileEditorMapping mapping = getMappingFor(fileName);
1430            if (mapping != null) {
1431                // backwards compatibility - add editors flagged as "default"
1432
related = mapping.getDeclaredDefaultEditors();
1433                for (int i = 0; i < related.length; i++) {
1434                    // we don't want to return duplicates
1435
if (!allRelated.contains(related[i])) {
1436                        // if it's not filtered, add it to the list
1437
if (!WorkbenchActivityHelper.filterItem(related[i])) {
1438                            allRelated.add(related[i]);
1439                        }
1440                    }
1441                }
1442                
1443                // add all filename editors to the nonDefaultList
1444
// we'll later try to add them all after content types are resolved
1445
// duplicates (ie: default editors) will be ignored
1446
nonDefaultFileEditors.addAll(Arrays.asList(mapping.getEditors()));
1447            }
1448            
1449            int index = fileName.lastIndexOf('.');
1450            if (index > -1) {
1451                String JavaDoc extension = "*" + fileName.substring(index); //$NON-NLS-1$
1452
mapping = getMappingFor(extension);
1453                if (mapping != null) {
1454                    related = mapping.getDeclaredDefaultEditors();
1455                    for (int i = 0; i < related.length; i++) {
1456                        // we don't want to return duplicates
1457
if (!allRelated.contains(related[i])) {
1458                            // if it's not filtered, add it to the list
1459
if (!WorkbenchActivityHelper.filterItem(related[i])) {
1460                                allRelated.add(related[i]);
1461                            }
1462                        }
1463                    }
1464                    nonDefaultFileEditors.addAll(Arrays.asList(mapping.getEditors()));
1465                }
1466            }
1467        }
1468        
1469        if (type != null) {
1470            // now add any objects directly related to the content type
1471
related = registry.getRelatedObjects(type);
1472            for (int i = 0; i < related.length; i++) {
1473                // we don't want to return duplicates
1474
if (!allRelated.contains(related[i])) {
1475                    // if it's not filtered, add it to the list
1476
if (!WorkbenchActivityHelper.filterItem(related[i])) {
1477                        allRelated.add(related[i]);
1478                    }
1479                }
1480            }
1481
1482        }
1483
1484        if (type != null) {
1485            // now add any indirectly related objects, walking up the content type hierarchy
1486
while ((type = type.getBaseType()) != null) {
1487                related = registry.getRelatedObjects(type);
1488                for (int i = 0; i < related.length; i++) {
1489                    // we don't want to return duplicates
1490
if (!allRelated.contains(related[i])) {
1491                        // if it's not filtered, add it to the list
1492
if (!WorkbenchActivityHelper.filterItem(related[i])) {
1493                            allRelated.add(related[i]);
1494                        }
1495                    }
1496                }
1497            }
1498        }
1499            
1500        // add all non-default editors to the list
1501
for (Iterator JavaDoc i = nonDefaultFileEditors.iterator(); i.hasNext();) {
1502            IEditorDescriptor editor = (IEditorDescriptor) i.next();
1503            if (!allRelated.contains(editor) && !WorkbenchActivityHelper.filterItem(editor)) {
1504                allRelated.add(editor);
1505            }
1506        }
1507        
1508        return (IEditorDescriptor []) allRelated.toArray(new IEditorDescriptor [allRelated
1509                .size()]);
1510    }
1511
1512    /**
1513     * Return the editors bound to this content type, either directly or indirectly.
1514     *
1515     * @param type the content type to check
1516     * @return the editors
1517     * @since 3.1
1518     *
1519     * TODO: this should be rolled in with the above findRelatedObjects code
1520     */

1521    public IEditorDescriptor [] getEditorsForContentType(IContentType type) {
1522        ArrayList JavaDoc allRelated = new ArrayList JavaDoc();
1523        if (type == null) {
1524            return new IEditorDescriptor [0];
1525        }
1526        
1527        Object JavaDoc [] related = relatedRegistry.getRelatedObjects(type);
1528        for (int i = 0; i < related.length; i++) {
1529            // we don't want to return duplicates
1530
if (!allRelated.contains(related[i])) {
1531                // if it's not filtered, add it to the list
1532
if (!WorkbenchActivityHelper.filterItem(related[i])) {
1533                    allRelated.add(related[i]);
1534                }
1535                
1536            }
1537        }
1538        
1539        // now add any indirectly related objects, walking up the content type hierarchy
1540
while ((type = type.getBaseType()) != null) {
1541            related = relatedRegistry.getRelatedObjects(type);
1542            for (int i = 0; i < related.length; i++) {
1543                // we don't want to return duplicates
1544
if (!allRelated.contains(related[i])) {
1545                    // if it's not filtered, add it to the list
1546
if (!WorkbenchActivityHelper.filterItem(related[i])) {
1547                        allRelated.add(related[i]);
1548                    }
1549                }
1550            }
1551        }
1552        
1553        return (IEditorDescriptor[]) allRelated.toArray(new IEditorDescriptor[allRelated.size()]);
1554    }
1555    
1556    /**
1557     * Get filemappings for all defined filetypes, including those defined by content type.
1558     *
1559     * @return the filetypes
1560     * @since 3.1
1561     */

1562    public IFileEditorMapping [] getUnifiedMappings() {
1563        IFileEditorMapping[] standardMappings = PlatformUI.getWorkbench()
1564                .getEditorRegistry().getFileEditorMappings();
1565        
1566        List JavaDoc allMappings = new ArrayList JavaDoc(Arrays.asList(standardMappings));
1567        // mock-up content type extensions into IFileEditorMappings
1568
IContentType [] contentTypes = Platform.getContentTypeManager().getAllContentTypes();
1569        for (int i = 0; i < contentTypes.length; i++) {
1570            IContentType type = contentTypes[i];
1571            String JavaDoc [] extensions = type.getFileSpecs(IContentType.FILE_EXTENSION_SPEC);
1572            for (int j = 0; j < extensions.length; j++) {
1573                String JavaDoc extension = extensions[j];
1574                boolean found = false;
1575                for (Iterator JavaDoc k = allMappings.iterator(); k.hasNext();) {
1576                    IFileEditorMapping mapping = (IFileEditorMapping) k.next();
1577                    if ("*".equals(mapping.getName()) && extension.equals(mapping.getExtension())) { //$NON-NLS-1$
1578
found = true;
1579                        break;
1580                    }
1581                }
1582                if (!found) {
1583                    MockMapping mockMapping = new MockMapping(type, "*", extension); //$NON-NLS-1$
1584
allMappings.add(mockMapping);
1585                }
1586            }
1587        
1588            String JavaDoc [] filenames = type.getFileSpecs(IContentType.FILE_NAME_SPEC);
1589            for (int j = 0; j < filenames.length; j++) {
1590                String JavaDoc wholename = filenames[j];
1591                int idx = wholename.indexOf('.');
1592                String JavaDoc name = idx == -1 ? wholename : wholename.substring(0, idx);
1593                String JavaDoc extension = idx == -1 ? "" : wholename.substring(idx + 1); //$NON-NLS-1$
1594

1595                boolean found = false;
1596                for (Iterator JavaDoc k = allMappings.iterator(); k.hasNext();) {
1597                    IFileEditorMapping mapping = (IFileEditorMapping) k.next();
1598                    if (name.equals(mapping.getName()) && extension.equals(mapping.getExtension())) {
1599                        found = true;
1600                        break;
1601                    }
1602                }
1603                if (!found) {
1604                    MockMapping mockMapping = new MockMapping(type, name, extension);
1605                    allMappings.add(mockMapping);
1606                }
1607            }
1608        }
1609        
1610        return (IFileEditorMapping []) allMappings
1611                .toArray(new IFileEditorMapping [allMappings.size()]);
1612    }
1613    
1614}
1615
1616
1617class MockMapping implements IFileEditorMapping {
1618
1619    private IContentType contentType;
1620    private String JavaDoc extension;
1621    private String JavaDoc filename;
1622    
1623    MockMapping(IContentType type, String JavaDoc name, String JavaDoc ext) {
1624        this.contentType = type;
1625        this.filename = name;
1626        this.extension = ext;
1627    }
1628
1629    public IEditorDescriptor getDefaultEditor() {
1630        IEditorDescriptor[] candidates = ((EditorRegistry) PlatformUI
1631                .getWorkbench().getEditorRegistry())
1632                .getEditorsForContentType(contentType);
1633        if (candidates.length == 0) {
1634            return null;
1635        }
1636        return candidates[0];
1637    }
1638
1639    public IEditorDescriptor[] getEditors() {
1640        return ((EditorRegistry) PlatformUI.getWorkbench().getEditorRegistry())
1641                .getEditorsForContentType(contentType);
1642    }
1643
1644    public IEditorDescriptor[] getDeletedEditors() {
1645        return new IEditorDescriptor[0];
1646    }
1647
1648    public String JavaDoc getExtension() {
1649        return extension;
1650    }
1651
1652    public ImageDescriptor getImageDescriptor() {
1653        IEditorDescriptor editor = getDefaultEditor();
1654        if (editor == null) {
1655            return WorkbenchImages
1656                    .getImageDescriptor(ISharedImages.IMG_OBJ_FILE);
1657        }
1658
1659        return editor.getImageDescriptor();
1660    }
1661
1662    public String JavaDoc getLabel() {
1663        return filename + '.' + extension;
1664    }
1665
1666    public String JavaDoc getName() {
1667        return filename;
1668    }
1669
1670    /* (non-Javadoc)
1671     * @see java.lang.Object#equals(java.lang.Object)
1672     */

1673    public boolean equals(Object JavaDoc obj) {
1674        if (this == obj) {
1675            return true;
1676        }
1677
1678        if (!(obj instanceof MockMapping)) {
1679            return false;
1680        }
1681
1682        MockMapping mapping = (MockMapping) obj;
1683        if (!this.filename.equals(mapping.filename)) {
1684            return false;
1685        }
1686
1687        if (!this.extension.equals(mapping.extension)) {
1688            return false;
1689        }
1690
1691        if (!Util.equals(this.getEditors(), mapping.getEditors())) {
1692            return false;
1693        }
1694        return Util.equals(this.getDeletedEditors(), mapping
1695                .getDeletedEditors());
1696    }
1697}
1698
1699
Popular Tags