blob: f1c8078d1f9e406679fda54e590eb725f1daefac [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008 xored software, Inc.
*
* 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:
* xored software, Inc. - initial API and Implementation (Alex Panchenko)
*******************************************************************************/
package org.eclipse.dltk.internal.core.builder;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.builder.IBuildParticipant;
import org.eclipse.dltk.core.builder.IBuildParticipantFactory;
import org.eclipse.dltk.utils.NatureExtensionManager;
import org.eclipse.osgi.util.NLS;
public class BuildParticipantManager extends NatureExtensionManager {
private static final String EXT_POINT = DLTKCore.PLUGIN_ID
+ ".buildParticipant"; //$NON-NLS-1$
public static class BuildParticipantDescriptor {
final IBuildParticipantFactory factory;
final String id;
final String name;
public final Set requirements = new HashSet();
/**
* @param factory
*/
public BuildParticipantDescriptor(IBuildParticipantFactory factory,
String id, String name) {
this.factory = factory;
this.id = id != null ? id : factory.getClass().getName();
this.name = name;
}
}
private BuildParticipantManager() {
super(EXT_POINT, BuildParticipantDescriptor.class);
}
private static final String REQUIRES = "requires"; //$NON-NLS-1$
private static final String REQUIRES_ID = "id"; //$NON-NLS-1$
private static final String ATTR_ID = "id"; //$NON-NLS-1$
private static final String ATTR_NAME = "name"; //$NON-NLS-1$
protected Object createInstanceByDescriptor(Object input)
throws CoreException {
final IConfigurationElement element = (IConfigurationElement) input;
final Object factory = element.createExecutableExtension(classAttr);
if (!(factory instanceof IBuildParticipantFactory)) {
return null;
}
final BuildParticipantDescriptor descriptor = new BuildParticipantDescriptor(
(IBuildParticipantFactory) factory, element
.getAttribute(ATTR_ID), element.getAttribute(ATTR_NAME));
final IConfigurationElement[] requires = element.getChildren(REQUIRES);
for (int i = 0; i < requires.length; ++i) {
final String id = requires[i].getAttribute(REQUIRES_ID);
if (id != null) {
descriptor.requirements.add(id);
}
}
return descriptor;
}
private static BuildParticipantManager instance = null;
private static BuildParticipantManager getInstance() {
if (instance == null) {
instance = new BuildParticipantManager();
}
return instance;
}
private static final IBuildParticipant[] NO_PARTICIPANTS = new IBuildParticipant[0];
/**
* Returns {@link IBuildParticipant} instances of the specified nature. If
* there are no build participants then the empty array is returned.
*
* @param project
* @param natureId
* @return
*/
public static IBuildParticipant[] getBuildParticipants(
IScriptProject project, String natureId) {
final BuildParticipantDescriptor[] descriptors = (BuildParticipantDescriptor[]) getInstance()
.getInstances(natureId);
if (descriptors == null || descriptors.length == 0) {
return NO_PARTICIPANTS;
}
return createParticipants(project, descriptors);
}
public static IBuildParticipant[] createParticipants(
IScriptProject project, BuildParticipantDescriptor[] descriptors) {
final IBuildParticipant[] result = new IBuildParticipant[descriptors.length];
final Set processed = new HashSet();
final Set created = new HashSet();
for (;;) {
final int iterationStartCount = created.size();
for (int i = 0; i < descriptors.length; ++i) {
final BuildParticipantDescriptor desc = descriptors[i];
if (!processed.contains(desc.id)
&& created.containsAll(desc.requirements)) {
processed.add(desc.id);
try {
final IBuildParticipant participant = desc.factory
.createBuildParticipant(project);
if (participant != null) {
result[created.size()] = participant;
created.add(desc.id);
}
} catch (CoreException e) {
final String tpl = Messages.BuildParticipantManager_buildParticipantCreateError;
DLTKCore.warn(NLS.bind(tpl, desc.id), e);
}
}
}
if (iterationStartCount == created.size()) {
break;
}
}
if (created.size() != result.length) {
final IBuildParticipant[] newResult = new IBuildParticipant[created
.size()];
System.arraycopy(result, 0, newResult, 0, created.size());
return newResult;
} else {
return result;
}
}
public static IBuildParticipant[] copyFirst(IBuildParticipant[] array,
int length) {
if (length == array.length) {
return array;
}
if (length == 0) {
return BuildParticipantManager.NO_PARTICIPANTS;
} else {
IBuildParticipant[] temp = new IBuildParticipant[length];
System.arraycopy(array, 0, temp, 0, length);
return temp;
}
}
}