/*******************************************************************************
* Copyright (c) 2006, 2007 Red Hat Inc. 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:
* Kyu Lee <klee@redhat.com> - initial API and implementation
*******************************************************************************/
package org.eclipse.linuxtools.internal.changelog.core;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.linuxtools.changelog.core.IFormatterChangeLogContrib;
import org.eclipse.linuxtools.changelog.core.IParserChangeLogContrib;
/**
* This class will manage extension related operations.
*
* @author klee
*
*/
public final class ChangeLogExtensionManager {
private static final ChangeLogExtensionManager EXM = new ChangeLogExtensionManager();
// These are used as a simple cache so we don't have to iterate over
// all extensions to formatContribution every time the action is invoked.
private IConfigurationElement cachedPrefFormatter = null;
private IConfigurationElement[] cachedInFileFormateters = null;
private IExtensionPoint parserExtensions = null;
private IExtensionPoint formatterExtensions = null;
private IParserChangeLogContrib parserContributor = null;
private IConfigurationElement formatterConfigElementToUse = null;
private ChangeLogExtensionManager() {
getParserContributions();
getFormatterContributions();
}
public static ChangeLogExtensionManager getExtensionManager() {
return EXM;
}
private void getFormatterContributions() {
formatterExtensions = Platform
.getExtensionRegistry()
.getExtensionPoint(
"org.eclipse.linuxtools.changelog.core", "formatterContribution"); //$NON-NLS-1$
}
private void getParserContributions() {
parserExtensions = Platform.getExtensionRegistry().getExtensionPoint(
"org.eclipse.linuxtools.changelog.core", "parserContribution"); //$NON-NLS-1$
}
public IParserChangeLogContrib getParserContributor(String editorName) {
if (parserExtensions != null) {
IConfigurationElement[] elements = parserExtensions
.getConfigurationElements();
for (int i = 0; i < elements.length; i++) {
if (elements[i].getName().equals("parser") // $NON-NLS-1$
&& (elements[i].getAttribute("editor") // $NON-NLS-1$
.equals(editorName))) {
//$NON-NLS-1$
try {
IConfigurationElement bob = elements[i];
parserContributor = (IParserChangeLogContrib) bob
.createExecutableExtension("class"); // $NON-NLS-1$
return parserContributor;
} catch (CoreException e) {
ChangelogPlugin.getDefault().getLog().log(
new Status(IStatus.ERROR, ChangelogPlugin.PLUGIN_ID,
IStatus.ERROR, e.getMessage(), e));
}
}
}
}
return null;
}
public IConfigurationElement getFormatterConfigElement() {
return formatterConfigElementToUse;
}
/**
* Fetches formatterName formatter from extension, but if there exists a inline
* formatter for entryFileName, then it uses that inline formatter.
* @param entryFilePath The full file name.
* @param formatterName The formatter name.
* @return The changelog formatter.
*/
public IFormatterChangeLogContrib getFormatterContributor(String entryFilePath, String formatterName) {
// extract just file name;
String fileName;
int lastDir = entryFilePath.lastIndexOf('/');
if ((lastDir >= 0) && (lastDir +1 <= entryFilePath.length()))
fileName = entryFilePath.substring(lastDir + 1, entryFilePath.length());
else
fileName = entryFilePath;
// We don't yet know which formatter to use
formatterConfigElementToUse = null;
// IFile file = null;
if (formatterExtensions != null) {
IConfigurationElement[] elements = formatterExtensions
.getConfigurationElements();
// cache the in-file formatters on the first run
if (cachedInFileFormateters == null) {
List<IConfigurationElement> inFileFormatters = new LinkedList<>();
for (int i = 0; i < elements.length; i++) {
IConfigurationElement formatterConfigElement = elements[i];
if (formatterConfigElement.getName().equals("formatter") // $NON-NLS-1$
&& formatterConfigElement.getAttribute("inFile") // $NON-NLS-1$
.equalsIgnoreCase("true")) { // $NON-NLS-1$
inFileFormatters.add(elements[i]);
}
}
cachedInFileFormateters = inFileFormatters
.toArray(new IConfigurationElement[] {});
}
// check if there is an in-file changelog formatter for the
// currently
// edited file
for (int i = 0; i < cachedInFileFormateters.length; i++) {
IConfigurationElement formatterConfigElement = cachedInFileFormateters[i];
IConfigurationElement[] patternElementTmp = formatterConfigElement
.getChildren();
// error check
if (patternElementTmp == null)
continue;
IConfigurationElement patternElement = patternElementTmp[0];
if (patternElement.getAttribute("pattern") == null) { // $NON-NLS-1$
ChangelogPlugin
.getDefault()
.getLog()
.log(
new Status(
IStatus.ERROR,
ChangelogPlugin.PLUGIN_ID,
IStatus.ERROR,
Messages.getString("ChangeLog.ErrNonPattern"), // $NON-NLS-1$
new Exception(Messages.getString("ChangeLog.ErrNonPattern")))); // $NON-NLS-1$
} else {
String filePattern = patternElement.getAttribute("pattern"); // $NON-NLS-1$
try {
Pattern pattern = Pattern.compile(filePattern);
Matcher fileMatcher = pattern.matcher(fileName);
// if the filename of the current editor matches the
// file
// pattern then we're done
if (fileMatcher.matches()) {
formatterConfigElementToUse = formatterConfigElement;
break;
}
} catch (PatternSyntaxException e) {
ChangelogPlugin.getDefault().getLog().log(
new Status(IStatus.ERROR, ChangelogPlugin.PLUGIN_ID,
IStatus.ERROR, e.getMessage(), e));
}
}
}
// if we haven't found an in-file formatter we try to get the user's
// prefered formatter
if (formatterConfigElementToUse == null) {
// we cache the user's preferred formatter on the first run, and
// whenever it changes
if (cachedPrefFormatter == null
|| !cachedPrefFormatter.getAttribute("name").equals( // $NON-NLS-1$
formatterName)) {
for (int i = 0; i < elements.length; i++) {
IConfigurationElement formatterConfigElement = elements[i];
if (formatterConfigElement.getName()
.equals("formatter") && formatterConfigElement.getAttribute("inFile").equalsIgnoreCase("false")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
if (formatterConfigElement.getAttribute("name") // $NON-NLS-1$
.equals(formatterName))
cachedPrefFormatter = formatterConfigElement;
break;
}
}
}
formatterConfigElementToUse = cachedPrefFormatter;
if (formatterConfigElementToUse == null) {
ChangelogPlugin
.getDefault()
.getLog()
.log(
new Status(
IStatus.ERROR,
ChangelogPlugin.PLUGIN_ID,
IStatus.ERROR,
Messages.getString("ChangeLog.ErrRetrieveFormatter"), // $NON-NLS-1$
new Exception(Messages.getString("ChangeLog.ErrRetrieveFormatter")))); // $NON-NLS-1$
return null;
}
}
}
try {
return (IFormatterChangeLogContrib) formatterConfigElementToUse
.createExecutableExtension("class"); // $NON-NLS-1$
} catch (CoreException e) {
ChangelogPlugin.getDefault().getLog().log(
new Status(IStatus.ERROR, ChangelogPlugin.PLUGIN_ID, IStatus.ERROR, e
.getMessage(), e));
e.printStackTrace();
}
return null;
}
}