From 7e7e45a917d6bc0e11e3e736125a6dcc8539c423 Mon Sep 17 00:00:00 2001
From: David Inglis
+ * Note that the
+ * Use the add
method checks for and eliminates
+ * duplicates based on identity (not equality). Likewise, the
+ * remove
method compares based on identity.
+ * getListeners
method when notifying listeners.
+ * Note that no garbage is created if no listeners are registered.
+ * The recommended code sequence for notifying all registered listeners
+ * of say, FooListener.eventHappened
, is:
+ *
+ * Object[] listeners = myListenerList.getListeners();
+ * for (int i = 0; i < listeners.length; ++i) {
+ * ((FooListener) listeners[i]).eventHappened(event);
+ * }
+ *
+ *
null
but initialized
+ * to an array of size capacity the first time a listener is added.
+ * Maintains invariant: listeners != null IFF size != 0
+ */
+ private Object[] listeners = null;
+
+ /**
+ * The empty array singleton instance, returned by getListeners()
+ * when size == 0.
+ */
+ private static final Object[] EmptyArray = new Object[0];
+
+ /**
+ * Creates a listener list with an initial capacity of 1.
+ */
+ public ListenerList() {
+ this(1);
+ }
+
+ /**
+ * Creates a listener list with the given initial capacity.
+ *
+ * @param capacity the number of listeners which this list can initially accept
+ * without growing its internal representation; must be at least 1
+ */
+ public ListenerList(int capacity) {
+ this.capacity = capacity;
+ }
+
+ /**
+ * Adds the given listener to this list. Has no effect if an identical listener
+ * is already registered.
+ *
+ * @param listener the listener
+ */
+ public void add(Object listener) {
+ if (size == 0) {
+ listeners = new Object[capacity];
+ } else {
+ // check for duplicates using identity
+ for (int i = 0; i < size; ++i) {
+ if (listeners[i] == listener) {
+ return;
+ }
+ }
+ // grow array if necessary
+ if (size == listeners.length) {
+ System.arraycopy(listeners, 0, listeners = new Object[size * 2 + 1], 0, size);
+ }
+ }
+ listeners[size++] = listener;
+ }
+
+ /**
+ * Removes all listeners from this list.
+ */
+ public void clear() {
+ size = 0;
+ listeners = null;
+ }
+
+ /**
+ * Returns an array containing all the registered listeners,
+ * in the order in which they were added.
+ * + * The resulting array is unaffected by subsequent adds or removes. + * If there are no listeners registered, the result is an empty array + * singleton instance (no garbage is created). + * Use this method when notifying listeners, so that any modifications + * to the listener list during the notification will have no effect on the + * notification itself. + *
+ * + * @return the list of registered listeners + */ + public Object[] getListeners() { + if (size == 0) + return EmptyArray; + Object[] result = new Object[size]; + System.arraycopy(listeners, 0, result, 0, size); + return result; + } + + /** + * Returns whether this listener list is empty. + * + * @returntrue
if there are no registered listeners, and
+ * false
otherwise
+ */
+ public boolean isEmpty() {
+ return size == 0;
+ }
+
+ /**
+ * Removes the given listener from this list. Has no effect if an identical
+ * listener was not already registered.
+ *
+ * @param listener the listener
+ */
+ public void remove(Object listener) {
+ for (int i = 0; i < size; ++i) {
+ if (listeners[i] == listener) {
+ if (size == 1) {
+ listeners = null;
+ size = 0;
+ } else {
+ System.arraycopy(listeners, i + 1, listeners, i, --size - i);
+ listeners[size] = null;
+ }
+ return;
+ }
+ }
+ }
+
+ /**
+ * Returns the number of registered listeners.
+ *
+ * @return the number of registered listeners
+ */
+ public int size() {
+ return size;
+ }
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/MakeTarget.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/MakeTarget.java
new file mode 100644
index 00000000000..509f4ab3ada
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/MakeTarget.java
@@ -0,0 +1,95 @@
+/*
+ * Created on 19-Aug-2003
+ *
+ * Copyright (c) 2002,2003 QNX Software Systems Ltd.
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+***********************************************************************/
+package org.eclipse.cdt.make.internal.core;
+
+import org.eclipse.cdt.make.core.IMakeTarget;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+public class MakeTarget implements IMakeTarget {
+
+ MakeTarget(String targetBuilderID, String targetName) {
+ // dinglis-TODO Auto-generated constructor stub
+ }
+
+ void setName(String name) {
+ // dinglis-TODO Auto-generated method stub
+ }
+
+ void setContainer(IContainer container) {
+ // dinglis-TODO Auto-generated method stub
+ }
+
+ public String getName() {
+ // dinglis-TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getTargetBuilderID() {
+ // dinglis-TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getBuilderID() {
+ // dinglis-TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean isStopOnError() {
+ // dinglis-TODO Auto-generated method stub
+ return false;
+ }
+
+ public void setStopOnError(boolean stopOnError) {
+ // dinglis-TODO Auto-generated method stub
+
+ }
+
+ public boolean isDefaultBuildCmd() {
+ // dinglis-TODO Auto-generated method stub
+ return false;
+ }
+
+ public void setUseDefaultBuildCmd(boolean useDefault) {
+ // dinglis-TODO Auto-generated method stub
+
+ }
+
+ public IPath getBuildCommand() {
+ // dinglis-TODO Auto-generated method stub
+ return null;
+ }
+
+ public void setBuildCommand(IPath command) {
+ // dinglis-TODO Auto-generated method stub
+
+ }
+
+ public String getBuildArguments() {
+ // dinglis-TODO Auto-generated method stub
+ return null;
+ }
+
+ public void setBuildArguments() {
+ // dinglis-TODO Auto-generated method stub
+
+ }
+
+ public IContainer getContainer() {
+ // dinglis-TODO Auto-generated method stub
+ return null;
+ }
+
+ public void build(IProgressMonitor monitor) throws CoreException {
+ // dinglis-TODO Auto-generated method stub
+
+ }
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/MakeTargetProvider.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/MakeTargetProvider.java
index 9c7077f203e..c90489dba93 100644
--- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/MakeTargetProvider.java
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/MakeTargetProvider.java
@@ -10,55 +10,213 @@
***********************************************************************/
package org.eclipse.cdt.make.internal.core;
-import org.eclipse.cdt.make.core.IMakeBuilderInfo;
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Vector;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
import org.eclipse.cdt.make.core.IMakeTarget;
import org.eclipse.cdt.make.core.IMakeTargetListener;
import org.eclipse.cdt.make.core.IMakeTargetProvider;
+import org.eclipse.cdt.make.core.MakeCorePlugin;
+import org.eclipse.cdt.make.core.MakeTargetEvent;
+import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
-public class MakeTargetProvider implements IMakeTargetProvider {
+public class MakeTargetProvider implements IMakeTargetProvider, IResourceChangeListener {
+ private static String TARGET_BUILD_EXT = MakeCorePlugin.getUniqueIdentifier() + ".MakeTargetBuilder"; //$NON-NLS-1$
+
+ private static String BUILD_TARGET_ELEMENT = "buildTargets"; //$NON-NLS-1$
+ private static String TARGET_ELEMENT = "target"; //$NON-NLS-1$
+
+ private ListenerList listeners = new ListenerList();
+ private HashMap projectMap = new HashMap();
+ private HashMap builderMap;
public MakeTargetProvider() {
}
- /* (non-Javadoc)
- * @see org.eclipse.cdt.make.core.IMakeTargetProvider#getTargets()
- */
- public IMakeTarget[] getTargets() {
- // dinglis-TODO Auto-generated method stub
- return null;
+ public IMakeTarget addTarget(IContainer container, String targetBuilderID, String targetName) throws CoreException {
+ if (container instanceof IWorkspaceRoot) {
+ throw new CoreException(new Status(IStatus.ERROR, MakeCorePlugin.getUniqueIdentifier(), -1, MakeCorePlugin.getResourceString("MakeTargetProvider.add_to_workspace_root"), null)); //$NON-NLS-1$
+ }
+ IProject project = container.getProject();
+ HashMap targetMap = (HashMap) projectMap.get(project);
+ if (targetMap == null) {
+ targetMap = initializeTargets(project);
+ }
+ ArrayList list = (ArrayList) targetMap.get(container);
+ MakeTarget target = new MakeTarget(targetBuilderID, targetName);
+ if (list != null && list.contains(target)) {
+ throw new CoreException(new Status(IStatus.ERROR, MakeCorePlugin.getUniqueIdentifier(), -1, MakeCorePlugin.getResourceString("MakeTargetProvider.target_exists"), null)); //$NON-NLS-1$
+ }
+ target.setContainer(container);
+ if (list == null) {
+ list = new ArrayList();
+ targetMap.put(container, list);
+ }
+ list.add(target);
+ notifyListeners(new MakeTargetEvent(this, MakeTargetEvent.TARGET_ADD, target));
+ return target;
}
- /* (non-Javadoc)
- * @see org.eclipse.cdt.make.core.IMakeTargetProvider#getTargets(org.eclipse.core.resources.IContainer)
- */
- public IMakeTarget[] getTargets(IContainer container) {
- // dinglis-TODO Auto-generated method stub
- return null;
+ public void removeTarget(IMakeTarget target) throws CoreException {
+ IProject project = target.getContainer().getProject();
+ HashMap targetMap = (HashMap) projectMap.get(project);
+ if (targetMap == null) {
+ targetMap = initializeTargets(project);
+ }
+ ArrayList list = (ArrayList) targetMap.get(target.getContainer());
+ if (list != null && !list.contains(target)) {
+ return;
+ }
+ list.remove(target);
+ if (list.size() == 0) {
+ targetMap.remove(list);
+ }
+ if (targetMap.size() == 0) {
+ projectMap.remove(project);
+ }
+ notifyListeners(new MakeTargetEvent(this, MakeTargetEvent.TARGET_REMOVED, target));
}
- /* (non-Javadoc)
- * @see org.eclipse.cdt.make.core.IMakeTargetProvider#getBuilderInfo(org.eclipse.cdt.make.core.IMakeTarget)
- */
- public IMakeBuilderInfo getBuilderInfo(IMakeTarget target) {
- // dinglis-TODO Auto-generated method stub
- return null;
+ public void renameTarget(IMakeTarget target, String name) throws CoreException {
+ IProject project = target.getContainer().getProject();
+ HashMap targetMap = (HashMap) projectMap.get(project);
+ if (targetMap == null) {
+ targetMap = initializeTargets(project);
+ }
+ ArrayList list = (ArrayList) targetMap.get(target.getContainer());
+ if (list != null && !list.contains(target)) {
+ throw new CoreException(new Status(IStatus.ERROR, MakeCorePlugin.getUniqueIdentifier(), -1, MakeCorePlugin.getResourceString("MakeTargetProvider.target_does_not_exists"), null)); //$NON-NLS-1$
+ }
+ ((MakeTarget) target).setName(name);
+ notifyListeners(new MakeTargetEvent(this, MakeTargetEvent.TARGET_CHANGED, target));
+ }
+
+ public IMakeTarget[] getTargets(IContainer container) throws CoreException {
+ IProject project = container.getProject();
+ HashMap targetMap = (HashMap) projectMap.get(project);
+ if (targetMap == null) {
+ targetMap = initializeTargets(project);
+ }
+ ArrayList list = (ArrayList) targetMap.get(container);
+ if (list != null) {
+ return (IMakeTarget[]) list.toArray(new IMakeTarget[list.size()]);
+ }
+ return new IMakeTarget[0];
+ }
+
+ private HashMap initializeTargets(IProject project) throws CoreException {
+ HashMap targetMap = new HashMap();
+ IPath targetFilePath = MakeCorePlugin.getDefault().getStateLocation().append(project.getName());
+ File targetFile = targetFilePath.toFile();
+ if (targetFile.exists()) {
+ try {
+ FileInputStream file = new FileInputStream(targetFile);
+ DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ Document document = parser.parse(file);
+ Node node = document.getFirstChild();
+ if (node.getNodeName().equals(BUILD_TARGET_ELEMENT)) {
+ NodeList list = node.getChildNodes();
+ for( int i = 0; i < list.getLength(); i++) {
+ Node item = list.item(i);
+ if ( item.getNodeName().equals(TARGET_ELEMENT)) {
+ NamedNodeMap attr = item.getAttributes();
+ MakeTarget target = new MakeTarget(attr.getNamedItem("targetID").getNodeValue(), attr.getNamedItem("name").getNodeValue()); //$NON-NLS-1$ //$NON-NLS-2$
+
+// targetMap.put(container, target);
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw new CoreException(
+ new Status(IStatus.ERROR, MakeCorePlugin.getUniqueIdentifier(), -1, MakeCorePlugin.getResourceString("MakeTargetProvider.failed_initializing_targets"), e)); //$NON-NLS-1$
+ }
+ }
+ return targetMap;
+ }
+
+ public IProject[] getTargetBuilderProjects() throws CoreException {
+ Vector tProj = new Vector();
+ IProject project[] = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+ for (int i = 0; i < project.length; i++) {
+ IProjectDescription description = project[i].getDescription();
+ ICommand builder[] = description.getBuildSpec();
+ for (int j = 0; j < builder.length; j++) {
+ if (builderMap.containsValue(builder[j].getBuilderName())) {
+ tProj.add(project[i]);
+ break;
+ }
+ }
+ }
+ return (IProject[]) tProj.toArray(new IProject[tProj.size()]);
+ }
+
+ public void startup() {
+ initializeBuilders();
+ ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
+ }
+
+ public void shutdown() {
+ ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
+ }
+
+ private void initializeBuilders() {
+ builderMap = new HashMap();
+
+ IExtensionPoint point = MakeCorePlugin.getDefault().getDescriptor().getExtensionPoint(MakeTargetProvider.TARGET_BUILD_EXT);
+ IExtension[] ext = point.getExtensions();
+ for (int i = 0; i < ext.length; i++) {
+ IConfigurationElement[] element = ext[i].getConfigurationElements();
+ for (int j = 0; j < element.length; j++) {
+ if (element[j].getName().equals("builder")) { //$NON-NLS-1$
+ String builderID = element[j].getAttribute("builderID"); //$NON-NLS-1$
+ String targetID = element[j].getAttribute("id"); //$NON-NLS-1$
+ builderMap.put(targetID, builderID);
+ }
+ }
+ }
+ }
+
+ private void notifyListeners(MakeTargetEvent event) {
+ Object[] list = listeners.getListeners();
+ for (int i = 0; i < list.length; i++) {
+ ((IMakeTargetListener) list[i]).targetChanged(event);
+ }
}
- /* (non-Javadoc)
- * @see org.eclipse.cdt.make.core.IMakeTargetProvider#addListener(org.eclipse.cdt.make.core.IMakeTargetListener)
- */
public void addListener(IMakeTargetListener listener) {
- // dinglis-TODO Auto-generated method stub
-
+ listeners.add(listener);
}
- /* (non-Javadoc)
- * @see org.eclipse.cdt.make.core.IMakeTargetProvider#removeListener(org.eclipse.cdt.make.core.IMakeTargetListener)
- */
public void removeListener(IMakeTargetListener listener) {
- // dinglis-TODO Auto-generated method stub
-
+ listeners.remove(listeners);
}
-}
+ public void resourceChanged(IResourceChangeEvent event) {
+ // dinglis-TODO listen for project that add/remove a target type builder
+
+ }
+}
\ No newline at end of file
diff --git a/build/org.eclipse.cdt.make.ui/.project b/build/org.eclipse.cdt.make.ui/.project
index 4d8db9f7ba4..bacedc79cd0 100644
--- a/build/org.eclipse.cdt.make.ui/.project
+++ b/build/org.eclipse.cdt.make.ui/.project
@@ -10,6 +10,8 @@