/******************************************************************************* | |
* Copyright (c) 2010 SAP AG, Walldorf | |
* 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: | |
* SAP AG - initial API and implementation | |
*******************************************************************************/ | |
package org.eclipse.platform.discovery.compatibility.internal.contributors.impl; | |
import java.util.ArrayList; | |
import java.util.Collection; | |
import org.eclipse.core.runtime.IContributor; | |
import org.eclipse.core.runtime.IExtensionRegistry; | |
import org.eclipse.platform.discovery.compatibility.internal.contributors.ContributionFailedException; | |
import org.eclipse.platform.discovery.compatibility.internal.contributors.IDynamicRegistryContributor; | |
import org.eclipse.platform.discovery.runtime.internal.xp.IContributionsReader; | |
import org.w3c.dom.Element; | |
/** | |
* A dynamic registry contributor contributes extensions to search console based on extensions to some other extension point, possibly org.eclipse.search | |
* @param <T> - the type of extensions based on which data is contributed. | |
*/ | |
public abstract class DynamicRegistryContributor<T> extends BasicRegistryContributor implements IDynamicRegistryContributor { | |
private final IContributionsReader<T> contributionsReader; | |
private final String targetExtensionPointId; | |
private final String targetElementName; | |
public DynamicRegistryContributor(IContributionsReader<T> contributionsReader, String targetExtensionPointId, String targetElementName) { | |
this.contributionsReader = contributionsReader; | |
this.targetExtensionPointId = targetExtensionPointId; | |
this.targetElementName = targetElementName; | |
} | |
@Override | |
public void contribute(IExtensionRegistry registry, IContributor contributor, Object token) throws ContributionFailedException { | |
Collection<T> failedContributors = new ArrayList<T>(); | |
for (T data : contributionsReader.readContributions()) { | |
Element plugin = createPluginSnippet(targetExtensionPointId); | |
configurePluginElement(data, plugin); | |
boolean success = writeToRegistry(plugin, registry, contributor, token, getContributionDescription(data)); | |
if(!success) { | |
/* | |
* it's very likely the implementation will never reach here. the underlying registry returns false if | |
* there was a parsing problem with the contribution (unexpected because the XML was generated by us) | |
* or an IOException (also unexpected, we're only dealing with in-memory objects). | |
* In case flow does reach here, create an error message and continue with the loop, contributing the rest of the stuff on a | |
* best-effort basis. | |
*/ | |
failedContributors.add(data); | |
} | |
} | |
if(!failedContributors.isEmpty()) { | |
throw new ContributionFailedException(getFailureMessage(failedContributors)); //$NON-NLS-1$ | |
} | |
} | |
protected abstract String getFailureMessage(Collection<T> failedContributors); | |
/** | |
* A description for the dynamic contribution which is being made based on <code>data</code>. It will be used as the "name" under which the contribution will be written in the | |
* platform extension registry. | |
*/ | |
protected abstract String getContributionDescription(T data); | |
/* adds an object type element to the plugin snippet passed, using the provided pageDescription*/ | |
private void configurePluginElement(T data, Element element) { | |
Element targetElement = element.getOwnerDocument().createElement(targetElementName); | |
configureTargetElement(targetElement, data); | |
addElementToPluginSnippet(element, targetElement); | |
} | |
/** | |
* Configure the target element attributes/children/executable extensions. It will already have its name set to <code>targetElementName</code> | |
*/ | |
protected abstract void configureTargetElement(Element element, T data); | |
} |