| /******************************************************************************* |
| * Copyright (c) 2000, 2003 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Common Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/cpl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.core.internal.filebuffers; |
| |
| |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.StringTokenizer; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IConfigurationElement; |
| import org.eclipse.core.runtime.IExtensionPoint; |
| import org.eclipse.core.runtime.ILog; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.content.IContentType; |
| import org.eclipse.core.runtime.content.IContentTypeManager; |
| |
| import org.eclipse.core.filebuffers.IDocumentFactory; |
| import org.eclipse.core.filebuffers.IDocumentSetupParticipant; |
| |
| |
| /** |
| * This registry manages sharable document factories. Document factories are specified |
| * in <code>plugin.xml</code> per file name extension. |
| */ |
| public class ExtensionsRegistry { |
| |
| private final static String WILDCARD= "*"; //$NON-NLS-1$ |
| |
| /** The mapping between name extensions and configuration elements describing document factories. */ |
| private Map fFactoryDescriptors= new HashMap(); |
| /** The mapping between configuration elements for document factories and instantiated document factories. */ |
| private Map fFactories= new HashMap(); |
| /** The mapping between name extensions and configuration elements describing document setup participants. */ |
| private Map fSetupParticipantDescriptors= new HashMap(); |
| /** The mapping between configuration elements for setup participants and instantiated setup participants. */ |
| private Map fSetupParticipants= new HashMap(); |
| |
| private IContentTypeManager fContentTypeManager= Platform.getContentTypeManager(); |
| |
| |
| /** |
| * Creates a new document factory registry and initializes it with the information |
| * found in the plug-in registry. |
| */ |
| public ExtensionsRegistry() { |
| initialize("documentCreation", "contentTypeId", true, fFactoryDescriptors); //$NON-NLS-1$ //$NON-NLS-2$ |
| initialize("documentCreation", "fileNames", fFactoryDescriptors); //$NON-NLS-1$ //$NON-NLS-2$ |
| initialize("documentCreation", "extensions", fFactoryDescriptors); //$NON-NLS-1$ //$NON-NLS-2$ |
| initialize("documentSetup", "contentTypeId", fSetupParticipantDescriptors); //$NON-NLS-1$ //$NON-NLS-2$ |
| initialize("documentSetup", "fileNames", fSetupParticipantDescriptors); //$NON-NLS-1$ //$NON-NLS-2$ |
| initialize("documentSetup", "extensions", fSetupParticipantDescriptors); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| /** |
| * Reads the comma-separated value from the given configuration element for the given attribute name and remembers |
| * the configuration element in the given map under the individual tokens of the attribute value. |
| * |
| * @param attributeName the name of the attribute |
| * @param element the configuration element |
| * @param map the map which remembers the configuration element |
| */ |
| private void read(String attributeName, IConfigurationElement element, Map map) { |
| String value= element.getAttribute(attributeName); |
| if (value != null) { |
| StringTokenizer tokenizer= new StringTokenizer(value, ","); //$NON-NLS-1$ |
| while (tokenizer.hasMoreTokens()) { |
| String token= tokenizer.nextToken().trim(); |
| |
| Set s= (Set) map.get(token); |
| if (s == null) { |
| s= new HashSet(); |
| map.put(token, s); |
| } |
| s.add(element); |
| } |
| } |
| } |
| |
| /** |
| * Reads the value from the given configuration element for the given attribute name and remembers |
| * the configuration element in the given map under the individual content type of the attribute value. |
| * |
| * @param attributeName the name of the attribute |
| * @param element the configuration element |
| * @param map the map which remembers the configuration element |
| */ |
| private void readContentType(String attributeName, IConfigurationElement element, Map map) { |
| String value= element.getAttribute(attributeName); |
| if (value != null) { |
| IContentType contentType= fContentTypeManager.getContentType(value); |
| Set s= (Set) map.get(contentType); |
| if (s == null) { |
| s= new HashSet(); |
| map.put(contentType, s); |
| } |
| s.add(element); |
| } |
| } |
| |
| /** |
| * Adds an entry to the log of this plug-in for the given status |
| * @param status the status to log |
| */ |
| private void log(IStatus status) { |
| ILog log= Platform.getPlugin(FileBuffersPlugin.PLUGIN_ID).getLog(); |
| log.log(status); |
| } |
| |
| /** |
| * Initializes this registry. It retrieves all implementers of the given |
| * extension point and remembers those implementers based on the |
| * file name extensions in the given map. |
| * |
| * @param extensionPointName the name of the extension point |
| * @param childElementName the name of the child elements |
| * @param descriptors the map to be filled |
| */ |
| private void initialize(String extensionPointName, String childElementName, Map descriptors) { |
| initialize(extensionPointName, childElementName, false, descriptors); |
| } |
| |
| /** |
| * Initializes this registry. It retrieves all implementers of the given |
| * extension point and remembers those implementers based on the |
| * file name extensions in the given map. |
| * |
| * @param extensionPointName the name of the extension point |
| * @param childElementName the name of the child elements |
| * @param isContentTypeId the child element is a content type id |
| * @param descriptors the map to be filled |
| */ |
| private void initialize(String extensionPointName, String childElementName, boolean isContentTypeId, Map descriptors) { |
| |
| IExtensionPoint extensionPoint= Platform.getExtensionRegistry().getExtensionPoint(FileBuffersPlugin.PLUGIN_ID, extensionPointName); |
| if (extensionPoint == null) { |
| log(new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, 0, FileBuffersMessages.getFormattedString("ExtensionsRegistry.error.extensionPointNotFound", new Object[] { extensionPointName}), null)); //$NON-NLS-1$ |
| return; |
| } |
| |
| IConfigurationElement[] elements= extensionPoint.getConfigurationElements(); |
| for (int i= 0; i < elements.length; i++) { |
| if (isContentTypeId) |
| readContentType(childElementName, elements[i], descriptors); |
| else |
| read(childElementName, elements[i], descriptors); |
| } |
| } |
| |
| /** |
| * Returns the executable extension for the given configuration element. |
| * If there is no instantiated extension remembered for this |
| * element, a new extension is created and put into the cache if it is of the requested type. |
| * |
| * @param entry the configuration element |
| * @param extensions the map of instantiated extensions |
| * @param extensionType the requested result type |
| * @return the executable extension for the given configuration element. |
| */ |
| private Object getExtension(IConfigurationElement entry, Map extensions, Class extensionType) { |
| Object extension= extensions.get(entry); |
| if (extension != null) |
| return extension; |
| |
| try { |
| extension= entry.createExecutableExtension("class"); //$NON-NLS-1$ |
| } catch (CoreException x) { |
| log(x.getStatus()); |
| } |
| |
| if (extensionType.isInstance(extension)) { |
| extensions.put(entry, extension); |
| return extension; |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Returns the first enumerated element of the given set. |
| * |
| * @param set the set from which to choose |
| * @return the selected configuration element |
| */ |
| private IConfigurationElement selectConfigurationElement(Set set) { |
| if (set != null && !set.isEmpty()) { |
| Iterator e= set.iterator(); |
| return (IConfigurationElement) e.next(); |
| } |
| return null; |
| } |
| |
| /** |
| * Returns a sharable document factory for the given file name extension. |
| * |
| * @param extension the name extension to be used for lookup |
| * @param isFileExtension <code>true</code> if the name extension is a file extension |
| * @return the sharable document factory or <code>null</code> |
| */ |
| private IDocumentFactory getDocumentFactory(String extension, boolean isFileExtension) { |
| Set set= null; |
| |
| if (!isFileExtension) { |
| IContentType[] contentTypes= fContentTypeManager.findContentTypesFor(extension); |
| int i= 0; |
| while (i < contentTypes.length && set == null) { |
| set= (Set) fFactoryDescriptors.get(contentTypes[i++]); |
| } |
| } |
| |
| if (set == null) |
| set= (Set) fFactoryDescriptors.get(extension); |
| |
| if (set != null) { |
| IConfigurationElement entry= selectConfigurationElement(set); |
| return (IDocumentFactory) getExtension(entry, fFactories, IDocumentFactory.class); |
| } |
| return null; |
| } |
| |
| /** |
| * Returns the set of setup participants for the given file name. |
| * |
| * @param extension the name extension to be used for lookup |
| * @param isFileExtension <code>true</code> if the name extension is a file extension |
| * @return the sharable set of document setup participants |
| */ |
| private List getDocumentSetupParticipants(String extension, boolean isFileExtension) { |
| Set resultSet= new HashSet(); |
| |
| if (!isFileExtension) { |
| IContentType[] contentTypes= fContentTypeManager.findContentTypesFor(extension); |
| int i= 0; |
| while (i < contentTypes.length) { |
| Set set= (Set) fFactoryDescriptors.get(contentTypes[i++]); |
| if (set != null) |
| resultSet.addAll(set); |
| } |
| } |
| |
| Set set= (Set) fSetupParticipantDescriptors.get(extension); |
| if (set != null) |
| resultSet.addAll(set); |
| |
| List participants= new ArrayList(); |
| Iterator e= resultSet.iterator(); |
| while (e.hasNext()) { |
| IConfigurationElement entry= (IConfigurationElement) e.next(); |
| Object participant= getExtension(entry, fSetupParticipants, IDocumentSetupParticipant.class); |
| if (participant != null) |
| participants.add(participant); |
| } |
| |
| return participants; |
| } |
| |
| /** |
| * Returns the sharable document factory for the given location. |
| * |
| * @param location the location for which to looked up the factory |
| * @return the sharable document factory |
| */ |
| public IDocumentFactory getDocumentFactory(IPath location) { |
| IDocumentFactory factory= getDocumentFactory(location.lastSegment(), false); |
| if (factory == null) |
| factory= getDocumentFactory(location.getFileExtension(), true); |
| if (factory == null) |
| factory= getDocumentFactory(WILDCARD, true); |
| return factory; |
| } |
| |
| /** |
| * Returns the sharable set of document setup participants for the given location. |
| * |
| * @param location the location for which to look up the setup participants |
| * @return the sharable set of document setup participants |
| */ |
| public IDocumentSetupParticipant[] getDocumentSetupParticipants(IPath location) { |
| List participants= new ArrayList(); |
| |
| List p= getDocumentSetupParticipants(location.lastSegment(), false); |
| if (p != null) |
| participants.addAll(p); |
| |
| p= getDocumentSetupParticipants(location.getFileExtension(), true); |
| if (p != null) |
| participants.addAll(p); |
| |
| p= getDocumentSetupParticipants(WILDCARD, true); |
| if (p != null) |
| participants.addAll(p); |
| |
| IDocumentSetupParticipant[] result= new IDocumentSetupParticipant[participants.size()]; |
| participants.toArray(result); |
| return result; |
| } |
| } |