| /******************************************************************************* |
| * Copyright (c) 2005, 2017 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.dltk.ast.parser; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IConfigurationElement; |
| import org.eclipse.core.runtime.IExecutableExtension; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.dltk.annotations.Nullable; |
| import org.eclipse.dltk.core.DLTKContributedExtension; |
| import org.eclipse.dltk.core.DLTKContributionExtensionManager; |
| import org.eclipse.dltk.core.DLTKCore; |
| |
| /** |
| * Manager responsible for all contributed <code>ISourceParser</code> extension |
| * implementations. |
| */ |
| public class SourceParserManager extends DLTKContributionExtensionManager { |
| |
| static final String SOURCE_PARSER_EXT_POINT = DLTKCore.PLUGIN_ID |
| + ".sourceParsers"; //$NON-NLS-1$ |
| |
| static final String PARSER_CONTRIBUTION_TAG = "parserContribution"; //$NON-NLS-1$ |
| |
| static final String PARSER_TAG = "parser"; //$NON-NLS-1$ |
| |
| static final String PARSER_CONFIGURATOR_TAG = "parserConfigurator"; //$NON-NLS-1$ |
| |
| static final String PARSER_CONFIGURATOR_CLASS = "class"; //$NON-NLS-1$ |
| |
| private static SourceParserManager instance; |
| |
| public static synchronized SourceParserManager getInstance() { |
| if (instance == null) { |
| instance = new SourceParserManager(); |
| } |
| return instance; |
| } |
| |
| public ISourceParser getSourceParserById(String id) { |
| return ((SourceParserContribution) getContributionById(id)) |
| .createSourceParser(null); |
| } |
| |
| @Override |
| protected boolean isNatureContribution(IConfigurationElement main) { |
| return PARSER_CONTRIBUTION_TAG.equals(main.getName()); // $NON-NLS-1$ |
| } |
| |
| @Override |
| protected String getContributionElementName() { |
| return PARSER_TAG; |
| } |
| |
| @Override |
| protected String getExtensionPoint() { |
| return SOURCE_PARSER_EXT_POINT; |
| } |
| |
| @Override |
| protected boolean isValidContribution(Object object) { |
| return (object instanceof ISourceParserFactory); |
| } |
| |
| @Override |
| protected Object configureContribution(Object object, |
| IConfigurationElement config) { |
| /* |
| * using the following delegate class allows for integration with the |
| * generic managed contribution preference page. |
| * |
| * not all source parsers are thread safe, so the factory allows us to |
| * create a new instance each time one is requested |
| */ |
| return new SourceParserContribution((ISourceParserFactory) object, |
| config); |
| } |
| |
| public ISourceParser getSourceParser(IProject project, String natureId) { |
| SourceParserContribution contribution = (SourceParserContribution) getSelectedContribution( |
| project, natureId); |
| if (contribution != null) { |
| return contribution.createSourceParser(project); |
| } |
| return null; |
| } |
| |
| static class SourceParserContribution extends DLTKContributedExtension { |
| |
| private final ISourceParserFactory factory; |
| private final IConfigurationElement config; |
| @Nullable |
| final ISourceParserConfigurator[] configurators; |
| |
| SourceParserContribution(ISourceParserFactory factory, |
| IConfigurationElement config) { |
| this.factory = factory; |
| this.config = config; |
| |
| /* |
| * this is a cheat - this class contains all the attributes of the |
| * configured extension, so leverage the code |
| * DLTKContributedExtension already provides |
| */ |
| setInitializationData(config, null, null); |
| this.configurators = getId() != null ? createConfigurators(getId()) |
| : null; |
| } |
| |
| ISourceParser createSourceParser(@Nullable IProject project) { |
| final ISourceParser parser = factory.createSourceParser(); |
| /* |
| * another cheat - not all source parsers are thread safe, so we |
| * need to create a new instance each time one is requested (hence |
| * the factory). |
| * |
| * the parser instance should be initialized with all it's attribute |
| * data |
| */ |
| if (parser instanceof IExecutableExtension) { |
| try { |
| ((IExecutableExtension) parser) |
| .setInitializationData(config, null, null); |
| } catch (CoreException e) { |
| DLTKCore.error(e); |
| } |
| } |
| if (configurators != null) { |
| for (ISourceParserConfigurator configurator : configurators) { |
| configurator.configure(parser, project); |
| } |
| } |
| |
| return parser; |
| } |
| |
| private static ISourceParserConfigurator[] createConfigurators( |
| String parserId) { |
| List<ISourceParserConfigurator> result = null; |
| for (IConfigurationElement element : Platform.getExtensionRegistry() |
| .getConfigurationElementsFor(SOURCE_PARSER_EXT_POINT)) { |
| if (PARSER_CONFIGURATOR_TAG.equals(element.getName()) |
| && parserId.equals(element.getAttribute("id"))) { //$NON-NLS-1$ |
| try { |
| final Object configurator = element |
| .createExecutableExtension( |
| PARSER_CONFIGURATOR_CLASS); |
| if (configurator instanceof ISourceParserConfigurator) { |
| if (result == null) { |
| result = new ArrayList<>(); |
| } |
| result.add( |
| (ISourceParserConfigurator) configurator); |
| } |
| } catch (CoreException e) { |
| DLTKCore.error(e); |
| } |
| } |
| } |
| return result != null |
| ? result.toArray( |
| new ISourceParserConfigurator[result.size()]) |
| : null; |
| } |
| } |
| } |