blob: aaae58f91dcebead75169a0768927e3873d95c5c [file] [log] [blame]
/*******************************************************************************
* 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;
}
}
}