Bug 391038 - Cannot build/clean projects created by previous versions of
ptp
diff --git a/rdt/org.eclipse.ptp.rdt.managedbuilder.xlc.ui/META-INF/MANIFEST.MF b/rdt/org.eclipse.ptp.rdt.managedbuilder.xlc.ui/META-INF/MANIFEST.MF
index eb162bf..c0517f3 100644
--- a/rdt/org.eclipse.ptp.rdt.managedbuilder.xlc.ui/META-INF/MANIFEST.MF
+++ b/rdt/org.eclipse.ptp.rdt.managedbuilder.xlc.ui/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %Bundle-Name
 Bundle-SymbolicName: org.eclipse.ptp.rdt.managedbuilder.xlc.ui;singleton:=true
-Bundle-Version: 2.0.1.qualifier
+Bundle-Version: 2.1.0.qualifier
 Bundle-Activator: org.eclipse.ptp.rdt.managedbuilder.xlc.ui.Activator
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
diff --git a/rdt/org.eclipse.ptp.rdt.managedbuilder.xlc.ui/pom.xml b/rdt/org.eclipse.ptp.rdt.managedbuilder.xlc.ui/pom.xml
index a9b2d1d..79ff36c 100644
--- a/rdt/org.eclipse.ptp.rdt.managedbuilder.xlc.ui/pom.xml
+++ b/rdt/org.eclipse.ptp.rdt.managedbuilder.xlc.ui/pom.xml
@@ -11,6 +11,6 @@
   </parent>
 
   <artifactId>org.eclipse.ptp.rdt.managedbuilder.xlc.ui</artifactId>
-  <version>2.0.1-SNAPSHOT</version>
+  <version>2.1.0-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
 </project>
diff --git a/rdt/org.eclipse.ptp.rdt.managedbuilder.xlc.ui/src/org/eclipse/ptp/rdt/managedbuilder/xlc/ui/Activator.java b/rdt/org.eclipse.ptp.rdt.managedbuilder.xlc.ui/src/org/eclipse/ptp/rdt/managedbuilder/xlc/ui/Activator.java
index 3d41e87..badfb44 100644
--- a/rdt/org.eclipse.ptp.rdt.managedbuilder.xlc.ui/src/org/eclipse/ptp/rdt/managedbuilder/xlc/ui/Activator.java
+++ b/rdt/org.eclipse.ptp.rdt.managedbuilder.xlc.ui/src/org/eclipse/ptp/rdt/managedbuilder/xlc/ui/Activator.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2010 IBM Corporation and others.
+ * Copyright (c) 2009, 2012 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
@@ -37,6 +37,7 @@
 	public void start(BundleContext context) throws Exception {
 		super.start(context);
 		plugin = this;
+		CProjectDescriptionListener.startListening();
 	}
 
 	/*
@@ -46,6 +47,7 @@
 	public void stop(BundleContext context) throws Exception {
 		plugin = null;
 		super.stop(context);
+		CProjectDescriptionListener.stopListening();
 	}
 
 	/**
diff --git a/rdt/org.eclipse.ptp.rdt.managedbuilder.xlc.ui/src/org/eclipse/ptp/rdt/managedbuilder/xlc/ui/CProjectDescriptionListener.java b/rdt/org.eclipse.ptp.rdt.managedbuilder.xlc.ui/src/org/eclipse/ptp/rdt/managedbuilder/xlc/ui/CProjectDescriptionListener.java
new file mode 100644
index 0000000..04fdb84
--- /dev/null
+++ b/rdt/org.eclipse.ptp.rdt.managedbuilder.xlc.ui/src/org/eclipse/ptp/rdt/managedbuilder/xlc/ui/CProjectDescriptionListener.java
@@ -0,0 +1,280 @@
+/*******************************************************************************

+ * Copyright (c) 2012 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.ptp.rdt.managedbuilder.xlc.ui;

+

+import java.util.LinkedList;

+import java.util.List;

+

+import org.eclipse.cdt.core.CCorePlugin;

+import org.eclipse.cdt.core.model.CoreModel;

+import org.eclipse.cdt.core.settings.model.CIncludePathEntry;

+import org.eclipse.cdt.core.settings.model.CMacroEntry;

+import org.eclipse.cdt.core.settings.model.CProjectDescriptionEvent;

+import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;

+import org.eclipse.cdt.core.settings.model.ICLanguageSetting;

+import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;

+import org.eclipse.cdt.core.settings.model.ICProjectDescription;

+import org.eclipse.cdt.core.settings.model.ICProjectDescriptionListener;

+import org.eclipse.cdt.core.settings.model.ICProjectDescriptionManager;

+import org.eclipse.cdt.core.settings.model.ICSettingEntry;

+import org.eclipse.cdt.managedbuilder.core.IConfiguration;

+import org.eclipse.cdt.managedbuilder.core.IInputType;

+import org.eclipse.cdt.managedbuilder.core.ITool;

+import org.eclipse.cdt.managedbuilder.core.IToolChain;

+import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;

+import org.eclipse.cdt.managedbuilder.internal.core.ManagedBuildInfo;

+import org.eclipse.cdt.managedbuilder.internal.core.ManagedProject;

+import org.eclipse.core.resources.IProject;

+import org.eclipse.core.resources.ResourcesPlugin;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IPath;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.Status;

+import org.eclipse.core.runtime.jobs.Job;

+import org.eclipse.jface.dialogs.MessageDialog;

+import org.eclipse.ptp.rdt.core.activator.Activator;

+import org.eclipse.ptp.rdt.managedbuilder.xlc.ui.messages.Messages;

+import org.eclipse.swt.widgets.Shell;

+import org.eclipse.ui.internal.Workbench;

+

+/**

+ * @author vkong

+ * @since 2.1

+ * 

+ */

+public class CProjectDescriptionListener implements ICProjectDescriptionListener {

+

+	private static CProjectDescriptionListener instance = new CProjectDescriptionListener();

+	protected boolean fOldInputType = false;

+

+	protected CProjectDescriptionListener() {

+	}

+

+	public static void startListening() {

+		CCorePlugin.getDefault().getProjectDescriptionManager().addCProjectDescriptionListener(instance, CProjectDescriptionEvent.LOADED);

+	}

+

+	public static void stopListening() {

+		CCorePlugin.getDefault().getProjectDescriptionManager().removeCProjectDescriptionListener(instance);

+	}

+	

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.cdt.core.settings.model.ICProjectDescriptionListener#handleEvent

+	 * (org.eclipse.cdt.core.settings.model.CProjectDescriptionEvent)

+	 */

+	public void handleEvent(final CProjectDescriptionEvent event) {

+		ICProjectDescription old= event.getOldCProjectDescription();

+		ICProjectDescription act= event.getNewCProjectDescription();

+		if (act != null) {

+			if (completedProjectCreation(old, act)) {

+				final IProject project = event.getProject();

+				final ICProjectDescriptionManager mngr = CoreModel.getDefault().getProjectDescriptionManager();

+				

+				Job convertToolChainJob = new Job(Messages.getString("CProjectDescriptionListener_jobName")) { //$NON-NLS-1$

+					

+					ICLanguageSettingEntry[] fCPPIncludePathEntries = null;

+					ICLanguageSettingEntry[] fCPPMacroEntries = null;

+					

+					protected IStatus run(IProgressMonitor monitor) {

+						ManagedBuildInfo info = (ManagedBuildInfo) ManagedBuildManager .getBuildInfo(project);

+						

+						if (info == null)

+							return Status.OK_STATUS;

+						

+						ManagedProject mProj = (ManagedProject) info.getManagedProject();

+

+						ICProjectDescription des = mngr.getProjectDescription(project, true /* writable */);

+						ICConfigurationDescription[] configurations = des.getConfigurations();

+						// ICConfigurationDescription activeConfiguration = des.getActiveConfiguration();

+

+						if (info != null) {

+							IConfiguration config = info.getDefaultConfiguration();

+							ICConfigurationDescription configDes = des.getActiveConfiguration();

+

+							IToolChain toolChain = config.getToolChain();

+							for (ITool tool : toolChain.getTools()) {

+								//find the C++ compiler

+								if (tool.getId().indexOf("org.eclipse.ptp.rdt.managedbuild.tool.xlc.cpp.compiler.exe.debug") != -1) { //$NON-NLS-1$

+									final ITool cppCompiler = tool;

+									for (final IInputType inputType : cppCompiler.getInputTypes()) {

+

+										// search for the obsolete input type

+										if (inputType.getId().indexOf("org.eclipse.ptp.rdt.managedbuilder.xlc.ui.cpp.c.compiler.input") != -1) { //$NON-NLS-1$

+

+											Workbench.getInstance().getDisplay().syncExec(new Runnable() {

+												

+												public void run() {

+													

+													Shell shell = new Shell();

+													String title = Messages.getString("CProjectDescriptionListener_dialogTitle"); //$NON-NLS-1$

+													String question = getConversionDialogString();

+													boolean continueConversion = MessageDialog.openQuestion(shell, title, question);  

+													

+													if (continueConversion) {

+														//remove it

+														cppCompiler.removeInputType(inputType);

+														fOldInputType = true;

+													}

+												}

+											

+											});

+											

+											if (fOldInputType) {

+												try {

+													//save changes

+													ManagedBuildManager.saveBuildInfo(project, true);

+													mngr.setProjectDescription(project, des, true /* force */, monitor);

+												} catch (CoreException e) {

+													Activator.log(e);

+												}

+											}

+											break;

+

+										}

+

+									}

+								}

+							}

+

+							if (fOldInputType) {

+								

+								// get the include paths and symbols settings from the C++ compiler for C++ source files

+								if (configDes.getRootFolderDescription() != null) {

+									ICLanguageSetting[] languageSettings = configDes.getRootFolderDescription().getLanguageSettings();

+									for (ICLanguageSetting langSetting : configDes.getRootFolderDescription().getLanguageSettings()) {

+

+										if (langSetting.getId().indexOf("org.eclipse.ptp.rdt.managedbuilder.xlc.ui.cpp.compiler.input") != -1) { //$NON-NLS-1$

+											fCPPIncludePathEntries = langSetting.getSettingEntries(ICSettingEntry.INCLUDE_PATH);

+											fCPPMacroEntries = langSetting.getSettingEntries(ICSettingEntry.MACRO);

+											break;

+										}

+									}

+

+									// update include paths and symbols settings of C source files for the C compiler

+									for (ICLanguageSetting langSetting : configDes.getRootFolderDescription().getLanguageSettings()) {

+										

+										if (langSetting.getId().indexOf("org.eclipse.ptp.rdt.managedbuilder.xlc.ui.c.compiler.input") != -1) { //$NON-NLS-1$

+											updateIncludeSettings(langSetting);

+											updateMacroSettings(langSetting);

+

+											try {

+												//save the changes

+												ManagedBuildManager.saveBuildInfo(project, true);

+												mngr.setProjectDescription(project, des, true /* force */, monitor);

+											} catch (CoreException e) {

+												Activator.log(e);

+											}

+

+											break;

+										}

+									}

+								}

+							}

+						}

+

+						return Status.OK_STATUS;

+					}

+					

+					private boolean updateMacroSettings(ICLanguageSetting langSetting) {

+						ICLanguageSettingEntry[] entries = langSetting.getSettingEntries(ICSettingEntry.MACRO);

+						List<ICLanguageSettingEntry> newEntries = new LinkedList<ICLanguageSettingEntry>();

+						for(ICLanguageSettingEntry entry : entries) {

+							newEntries.add(entry);

+						}

+						

+						boolean entriesChanged = false;

+																	

+						// look for settings

+						for (ICLanguageSettingEntry cppMacroEntry : fCPPMacroEntries) {

+							String symbol = ((CMacroEntry)cppMacroEntry).getName();

+							boolean symbolFound = false;

+							

+							for (ICLanguageSettingEntry entry : entries) {

+								if (((CMacroEntry) entry).getName().equals(symbol)) {

+									symbolFound = true; // it's already there, so don't set it

+									break;

+								}

+							}

+							

+							// if we didn't find the symbol, add it

+							if(!symbolFound) {

+								entriesChanged = true;

+								CMacroEntry newEntry = new CMacroEntry(symbol, cppMacroEntry.getValue(), cppMacroEntry.getFlags());

+								newEntries.add(newEntry);

+							}

+						}

+							

+						// if we changed the entries, then set the new ones

+						if(entriesChanged) {

+							langSetting.setSettingEntries(ICSettingEntry.MACRO, newEntries.toArray(new ICLanguageSettingEntry[0]));

+						}

+						

+						return entriesChanged;		

+					}

+

+					private boolean updateIncludeSettings(ICLanguageSetting langSetting) {

+						ICLanguageSettingEntry[] entries = langSetting.getSettingEntries(ICSettingEntry.INCLUDE_PATH);

+						List<ICLanguageSettingEntry> newEntries = new LinkedList<ICLanguageSettingEntry>();

+						for(ICLanguageSettingEntry entry : entries) {

+							newEntries.add(entry);

+						}

+						

+						boolean entriesChanged = false;

+																	

+						// look for settings					

+						for (ICLanguageSettingEntry cppIncludePathEntry : fCPPIncludePathEntries) {

+							IPath path = ((CIncludePathEntry)cppIncludePathEntry).getLocation();

+

+							boolean pathFound = false;

+							

+							for (ICLanguageSettingEntry entry : entries) {

+								if (((CIncludePathEntry) entry).getLocation().equals(path)) {

+									pathFound = true; // it's already there, so don't set it

+									break;

+								}

+							}

+							

+							// if we didn't find the path, add it

+							if(!pathFound) {

+								entriesChanged = true;

+								CIncludePathEntry newEntry = new CIncludePathEntry(path, cppIncludePathEntry.getFlags());

+								newEntries.add(newEntry);

+							}

+						}

+							

+						// if we changed the entries, then set the new ones

+						if(entriesChanged) {

+							langSetting.setSettingEntries(ICSettingEntry.INCLUDE_PATH, newEntries.toArray(new ICLanguageSettingEntry[0]));

+						}

+						

+						return entriesChanged;

+					}

+				};

+				

+				convertToolChainJob.setRule(ResourcesPlugin.getWorkspace().getRoot());

+				convertToolChainJob.schedule();

+			}

+		}

+	}

+

+	private boolean completedProjectCreation(ICProjectDescription old, ICProjectDescription act) {

+		return (old == null || old.isCdtProjectCreating()) && !act.isCdtProjectCreating();

+	}

+	

+	protected String getConversionDialogString() {

+		return Messages.getString("CProjectDescriptionListener_dialogQuestion"); //$NON-NLS-1$

+	}

+}

diff --git a/rdt/org.eclipse.ptp.rdt.managedbuilder.xlc.ui/src/org/eclipse/ptp/rdt/managedbuilder/xlc/ui/messages/messages.properties b/rdt/org.eclipse.ptp.rdt.managedbuilder.xlc.ui/src/org/eclipse/ptp/rdt/managedbuilder/xlc/ui/messages/messages.properties
index 352708f..897651f 100644
--- a/rdt/org.eclipse.ptp.rdt.managedbuilder.xlc.ui/src/org/eclipse/ptp/rdt/managedbuilder/xlc/ui/messages/messages.properties
+++ b/rdt/org.eclipse.ptp.rdt.managedbuilder.xlc.ui/src/org/eclipse/ptp/rdt/managedbuilder/xlc/ui/messages/messages.properties
@@ -1,5 +1,5 @@
 ###############################################################################
-# Copyright (c) 2010 IBM Corporation and others.
+# Copyright (c) 2010, 2012 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
@@ -8,7 +8,9 @@
 # Contributors:
 #     IBM Corporation - initial API and implementation
 ###############################################################################
-
+CProjectDescriptionListener_dialogTitle=Existing project settings will be overriden
+CProjectDescriptionListener_jobName=Update project's tool chain
+CProjectDescriptionListener_dialogQuestion=Projects created before PTP 4.2 will need to be converted for version 4.2.x.  Would you like to continue the conversion?  \n\nPlease note that after the conversion, the project will no longer work in previous version of PTP.
 REMOTEXLCompilerPropertyPage_0=Remote Compiler Root Path on {0}:
 XLCompilerPropertyPage_ErrorMsg=Compiler path does not exist on {0}
 
diff --git a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/scannerinfo/RemoteIncludeTab.java b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/scannerinfo/RemoteIncludeTab.java
index bae6b8e..5d1c2e5 100644
--- a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/scannerinfo/RemoteIncludeTab.java
+++ b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/scannerinfo/RemoteIncludeTab.java
@@ -10,13 +10,8 @@
  *******************************************************************************/
 package org.eclipse.ptp.internal.rdt.ui.scannerinfo;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import org.eclipse.cdt.core.settings.model.CIncludePathEntry;
-import org.eclipse.cdt.core.settings.model.ICLanguageSetting;
 import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
-import org.eclipse.cdt.core.settings.model.ICResourceDescription;
 import org.eclipse.cdt.ui.newui.IncludeTab;
 import org.eclipse.ptp.internal.rdt.ui.RDTHelpContextIds;
 import org.eclipse.ptp.internal.rdt.ui.RSEUtils;
@@ -92,22 +87,4 @@
 			}
 		}
 	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.cdt.ui.newui.AbstractLangsListTab#getLangSetting(org.eclipse.cdt.core.settings.model.ICResourceDescription)
-	 */
-	@Override
-	public ICLanguageSetting[] getLangSetting(ICResourceDescription rcDes) {
-		ICLanguageSetting[] langSettings_orig = super.getLangSetting(rcDes);
-		List<ICLanguageSetting> langSettings = new ArrayList<ICLanguageSetting>();
-
-		// bug 378579 - remove the old Remote XL C++ Compiler's C source file input type in case 
-		// this is a project created before the fix for bug 378579
-		for (int i = 0; i < langSettings_orig.length; i++) {
-			if (langSettings_orig[i].getId().indexOf("org.eclipse.ptp.rdt.managedbuilder.xlc.ui.cpp.c.compiler.input") == -1) { //$NON-NLS-1$
-				langSettings.add(langSettings_orig[i]);
-			}
-		}
-		return langSettings.toArray(new ICLanguageSetting[langSettings.size()]);
-	}
 }
diff --git a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/scannerinfo/RemoteSymbolTab.java b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/scannerinfo/RemoteSymbolTab.java
index d5dbbcf..6e1b780 100644
--- a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/scannerinfo/RemoteSymbolTab.java
+++ b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/scannerinfo/RemoteSymbolTab.java
@@ -10,11 +10,6 @@
  *******************************************************************************/ 
 package org.eclipse.ptp.internal.rdt.ui.scannerinfo;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.cdt.core.settings.model.ICLanguageSetting;
-import org.eclipse.cdt.core.settings.model.ICResourceDescription;
 import org.eclipse.cdt.ui.newui.SymbolTab;
 import org.eclipse.ptp.internal.rdt.ui.RDTHelpContextIds;
 
@@ -23,22 +18,5 @@
 	public String getHelpContextId() {
 		return RDTHelpContextIds.REMOTE_SYMBOL_TAB;
 	}
-	
-	/* (non-Javadoc)
-	 * @see org.eclipse.cdt.ui.newui.AbstractLangsListTab#getLangSetting(org.eclipse.cdt.core.settings.model.ICResourceDescription)
-	 */
-	@Override
-	public ICLanguageSetting[] getLangSetting(ICResourceDescription rcDes) {
-		ICLanguageSetting[] langSettings_orig = super.getLangSetting(rcDes);
-		List<ICLanguageSetting> langSettings = new ArrayList<ICLanguageSetting>();
-		
-		// bug 378579 - remove the old Remote XL C++ Compiler's C source file input type in case 
-		// this is a project created before the fix for bug 378579
-		for (int i = 0; i < langSettings_orig.length; i++) {
-			if (langSettings_orig[i].getId().indexOf("org.eclipse.ptp.rdt.managedbuilder.xlc.ui.cpp.c.compiler.input") == -1) { //$NON-NLS-1$
-				langSettings.add(langSettings_orig[i]);
-			}
-		}
-		return langSettings.toArray(new ICLanguageSetting[langSettings.size()]);
-	}
+
 }