--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cdt/cdt_6_0_x/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionManager.java Wed Jul 29 14:30:25 2009 -0500
@@ -0,0 +1,2678 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 Intel 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:
+ * Intel Corporation - Initial API and implementation
+ * Markus Schorn (Wind River Systems)
+ * IBM Corporation
+ * James Blackburn (Broadcom Corp.)
+ * Alex Blewitt Bug 132511 - nature order not preserved
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.settings.model;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.FactoryConfigurationError;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.model.CModelException;
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.model.ICElementDelta;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.settings.model.CExternalSetting;
+import org.eclipse.cdt.core.settings.model.CProjectDescriptionEvent;
+import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
+import org.eclipse.cdt.core.settings.model.ICDescriptionDelta;
+import org.eclipse.cdt.core.settings.model.ICFileDescription;
+import org.eclipse.cdt.core.settings.model.ICFolderDescription;
+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.ICProjectDescriptionWorkspacePreferences;
+import org.eclipse.cdt.core.settings.model.ICResourceDescription;
+import org.eclipse.cdt.core.settings.model.ICSettingBase;
+import org.eclipse.cdt.core.settings.model.ICSettingEntry;
+import org.eclipse.cdt.core.settings.model.ICSettingObject;
+import org.eclipse.cdt.core.settings.model.ICSettingsStorage;
+import org.eclipse.cdt.core.settings.model.ICSourceEntry;
+import org.eclipse.cdt.core.settings.model.ICStorageElement;
+import org.eclipse.cdt.core.settings.model.ICTargetPlatformSetting;
+import org.eclipse.cdt.core.settings.model.extension.CConfigurationData;
+import org.eclipse.cdt.core.settings.model.extension.CConfigurationDataProvider;
+import org.eclipse.cdt.core.settings.model.extension.CFileData;
+import org.eclipse.cdt.core.settings.model.extension.CFolderData;
+import org.eclipse.cdt.core.settings.model.extension.CLanguageData;
+import org.eclipse.cdt.core.settings.model.extension.CResourceData;
+import org.eclipse.cdt.core.settings.model.extension.ICProjectConverter;
+import org.eclipse.cdt.core.settings.model.extension.impl.CDataFactory;
+import org.eclipse.cdt.core.settings.model.util.CDataUtil;
+import org.eclipse.cdt.core.settings.model.util.CSettingEntryFactory;
+import org.eclipse.cdt.core.settings.model.util.KindBasedStore;
+import org.eclipse.cdt.core.settings.model.util.ListComparator;
+import org.eclipse.cdt.core.settings.model.util.PathSettingsContainer;
+import org.eclipse.cdt.core.settings.model.util.PatternNameMap;
+import org.eclipse.cdt.internal.core.CConfigBasedDescriptorManager;
+import org.eclipse.cdt.internal.core.model.CElementDelta;
+import org.eclipse.cdt.internal.core.settings.model.CExternalSettinsDeltaCalculator.ExtSettingsDelta;
+import org.eclipse.cdt.internal.core.settings.model.xml.InternalXmlStorageElement;
+import org.eclipse.cdt.internal.core.settings.model.xml.XmlStorage;
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.filesystem.IFileStore;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.ISavedState;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.content.IContentType;
+import org.eclipse.core.runtime.content.IContentTypeManager;
+import org.eclipse.core.runtime.jobs.IJobManager;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
+import org.osgi.framework.Version;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.ProcessingInstruction;
+import org.xml.sax.SAXException;
+
+import com.ibm.icu.text.MessageFormat;
+
+/**
+ * The CProjectDescriptionManager is to marshall the loading and storing
+ * of CDT Project Descriptions.
+ *
+ * This class delegates loading and store of the project model to the appropriate
+ * AbstractCProjectDescriptionStorage for the Project Description. [ Discovered at Project load
+ * time.]
+ *
+ * Users should not synchronize on the singleton instance of this class. It is the job of
+ * the AbstractCProjectDescriptionStorage to ensure thread safe access to the backing store
+ * as described in that interface.
+ *
+ * Previously this class created and persisted
+ * @see ICProjectDescriptionManager
+ */
+public class CProjectDescriptionManager implements ICProjectDescriptionManager {
+ public static final int INTERNAL_GET_IGNORE_CLOSE = 1 << 31 ;
+
+ private static final String VERSION_ELEMENT_NAME = "fileVersion"; //$NON-NLS-1$
+ /** Preference Version 4.0 & 5.0 are equivalent for us. Version was inadvertently bumped
+ * when during project description storage work.
+ * This is the minimum preference version we support loading.*/
+ public static final Version MIN_DESCRIPTION_VERSION = new Version("4.0"); //$NON-NLS-1$
+ /** Current preference file storage version */
+ public static final Version DESCRIPTION_VERSION = new Version("5.0"); //$NON-NLS-1$
+ public final static String MODULE_ID = "org.eclipse.cdt.core.settings"; //$NON-NLS-1$
+ static final String CONFIGURATION = "cconfiguration"; //$NON-NLS-1$
+ private static final ICLanguageSettingEntry[] EMPTY_LANGUAGE_SETTINGS_ENTRIES_ARRAY = new ICLanguageSettingEntry[0];
+ private static final ICElementDelta[] EMPTY_CELEMENT_DELTA = new ICElementDelta[0];
+ private static final ICLanguageSetting[] EMPTY_LANGUAGE_SETTINGS_ARRAY = new ICLanguageSetting[0];
+ private static final String PREFERENCES_STORAGE = "preferences"; //$NON-NLS-1$
+ private static final String PREFERENCE_BUILD_SYSTEM_ELEMENT = "buildSystem"; //$NON-NLS-1$
+ private static final String PREFERENCES_ELEMENT = "preferences"; //$NON-NLS-1$
+ private static final String ID = "id"; //$NON-NLS-1$
+ private static final String PREFERENCE_CFG_ID_PREFIX = "preference."; //$NON-NLS-1$
+ private static final String PREFERENCE_CFG_NAME = SettingsModelMessages.getString("CProjectDescriptionManager.15"); //$NON-NLS-1$
+ private static final String ROOT_PREFERENCE_ELEMENT = "preferences"; //$NON-NLS-1$
+ private static final String DEFAULT_CFG_ID_PREFIX = CCorePlugin.PLUGIN_ID + ".default.config"; //$NON-NLS-1$
+ private static final String DEFAULT_CFG_NAME = "Configuration"; //$NON-NLS-1$
+
+ private static final QualifiedName SCANNER_INFO_PROVIDER_PROPERTY = new QualifiedName(CCorePlugin.PLUGIN_ID, "scannerInfoProvider"); //$NON-NLS-1$
+
+ static class CompositeWorkspaceRunnable implements IWorkspaceRunnable {
+ private List<IWorkspaceRunnable> fRunnables = new ArrayList<IWorkspaceRunnable>();
+ private String fName;
+ private boolean fStopOnErr;
+
+ CompositeWorkspaceRunnable(String name){
+ if(name == null)
+ name = ""; //$NON-NLS-1$
+ fName = name;
+ }
+
+ public void add(IWorkspaceRunnable runnable){
+ fRunnables.add(runnable);
+ }
+
+ public void run(IProgressMonitor monitor) throws CoreException {
+ try {
+ monitor.beginTask(fName, fRunnables.size());
+
+ for(Iterator<IWorkspaceRunnable> iter = fRunnables.iterator(); iter.hasNext();){
+ IWorkspaceRunnable r = iter.next();
+ IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 1);
+ try {
+ r.run(subMonitor);
+ } catch (CoreException e){
+ if(fStopOnErr)
+ throw e;
+ } catch (RuntimeException e) {
+ if(fStopOnErr)
+ throw e;
+ } finally {
+ subMonitor.done();
+ }
+ }
+ } finally {
+ monitor.done();
+ }
+ }
+
+ public boolean isEmpty(){
+ return fRunnables.isEmpty();
+ }
+ }
+
+ /**
+ * Container class for ICProjectDescription change listeners
+ */
+ private static class ListenerDescriptor{
+ final ICProjectDescriptionListener fListener;
+ final int fEventTypes;
+
+ public ListenerDescriptor(ICProjectDescriptionListener listener, int eventTypes) {
+ fListener = listener;
+ fEventTypes = eventTypes;
+ }
+
+ public boolean handlesEvent(int eventType){
+ return (eventType & fEventTypes) != 0;
+ }
+ @Override
+ public int hashCode() {
+ return fListener.hashCode();
+ }
+ @Override
+ public boolean equals(Object obj) {
+ return fListener.equals(obj);
+ }
+ }
+
+ private volatile Map<String, CConfigurationDataProviderDescriptor> fProviderMap;
+ private volatile CProjectConverterDesciptor fConverters[];
+ /** Set of Listeners listening for Project Description Deltas */
+ private Set<ListenerDescriptor> fListeners = new CopyOnWriteArraySet<ListenerDescriptor>();
+ private Map<String, CConfigurationDescriptionCache> fPreferenceMap = new HashMap<String, CConfigurationDescriptionCache>();
+ private CConfigBasedDescriptorManager fDescriptorManager;
+ private ResourceChangeHandler fRcChangeHandler;
+ private CProjectDescriptionWorkspacePreferences fPreferences;
+ private boolean fAllowEmptyCreatingDescription = true; // allowed by default
+
+ private ICDataProxyContainer fPrefUpdater = new ICDataProxyContainer(){
+
+ public void updateChild(CDataProxy child, boolean write) {
+ if(write){
+ try {
+ ((CConfigurationDescription)child).doWritable();
+ } catch (CoreException e) {
+ CCorePlugin.log(e);
+ }
+ }
+ }
+
+ public ICSettingObject[] getChildSettings() {
+ return fPreferenceMap.values().toArray(new CConfigurationDescriptionCache[fPreferenceMap.size()]);
+ }
+ };
+
+ /** The CProjectDescriptionManager instance */
+ private static volatile CProjectDescriptionManager fInstance;
+
+ private CProjectDescriptionManager(){}
+
+ public static CProjectDescriptionManager getInstance(){
+ if(fInstance == null)
+ synchronized(CProjectDescriptionManager.class) {
+ if (fInstance == null)
+ fInstance = new CProjectDescriptionManager();
+ }
+ return fInstance;
+ }
+
+ public void projectClosedRemove(IProject project) {
+ CProjectDescriptionStorageManager.getInstance().projectClosedRemove(project);
+ }
+
+ public void projectMove(IProject from, IProject to) {
+ CProjectDescriptionStorageManager.getInstance().projectMove(from, to);
+ }
+
+
+ public Job startup(){
+ if(fRcChangeHandler == null){
+ fRcChangeHandler = new ResourceChangeHandler();
+
+ ResourcesPlugin.getWorkspace().addResourceChangeListener(
+ fRcChangeHandler,
+ IResourceChangeEvent.POST_CHANGE
+ | IResourceChangeEvent.PRE_DELETE
+ | IResourceChangeEvent.PRE_CLOSE
+ /*| IResourceChangeEvent.POST_BUILD*/);
+
+ if(fDescriptorManager == null){
+ fDescriptorManager = CConfigBasedDescriptorManager.getInstance();
+ fDescriptorManager.startup();
+ }
+
+ CExternalSettingsManager.getInstance().startup();
+ }
+ return createPostStartupJob();
+ }
+
+ private Job createPostStartupJob() {
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ Job rcJob = new Job(SettingsModelMessages.getString("CProjectDescriptionManager.0")){ //$NON-NLS-1$
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ try{
+ startSaveParticipant();
+ } catch (CoreException e){
+ CCorePlugin.log(e);
+ return e.getStatus();
+ }
+ return new Status(
+ IStatus.OK,
+ CCorePlugin.PLUGIN_ID,
+ IStatus.OK,
+ "", //$NON-NLS-1$
+ null);
+ }
+ };
+
+ rcJob.setRule(root);
+ rcJob.setPriority(Job.INTERACTIVE);
+ rcJob.setSystem(true);
+ return rcJob;
+ }
+
+ /*
+ * This method adds a save participant and resource change listener
+ * Throws CoreException if the methods fails to add a save participant.
+ * The resource change listener in not added in this case either.
+ */
+ private void startSaveParticipant() throws CoreException{
+ // Set up a listener for resource change events
+ ISavedState lastState =
+ ResourcesPlugin.getWorkspace().addSaveParticipant(CCorePlugin.getDefault(), fRcChangeHandler);
+
+ if (lastState != null) {
+ lastState.processResourceChangeEvents(fRcChangeHandler);
+ }
+ }
+
+ public void shutdown(){
+ CExternalSettingsManager.getInstance().shutdown();
+
+ if(fDescriptorManager != null) {
+ fDescriptorManager.shutdown();
+ fDescriptorManager = null;
+ }
+
+ if(fRcChangeHandler != null) {
+ ResourcesPlugin.getWorkspace().removeResourceChangeListener(fRcChangeHandler);
+ fRcChangeHandler = null;
+ }
+
+ CProjectDescriptionStorageManager.getInstance().shutdown();
+ }
+
+ public ICProjectDescription getProjectDescription(IProject project, boolean write) {
+ return getProjectDescription(project, true, write);
+ }
+
+ public ICProjectDescription getProjectDescription(IProject project, boolean load, boolean write) {
+ int flags = load ? 0 : GET_IF_LOADDED;
+ flags |= write ? GET_WRITABLE : 0;
+
+ return getProjectDescription(project, flags);
+ }
+
+ public ICProjectDescription getProjectDescription(IProject project, int flags) {
+ AbstractCProjectDescriptionStorage storage = getProjectDescriptionStorage(project);
+ if (storage != null) {
+ try {
+ return storage.getProjectDescription(flags, new NullProgressMonitor());
+ } catch (CoreException e) {
+ // FIXME Currently the resource change handler ResourceChangeHandler.getProjectDescription(...)
+ // Does this when the project is closed. Don't log an error or the tests will fail
+// CCorePlugin.log(e);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Run the workspace modification in the current thread using the workspace scheduling rule
+ * Equivalent to: <code>runWspModification(IWorkspaceRunnable, ResourcecPlugin.getWorkspace().getRoot(), IProgressMonitor)</code>
+ *<br/><br/>
+ * Note that if the workspace is locked, or the current job / thread doesn't contain the workspace
+ * scheduling rule, then we schedule a job to run the {@link IWorkspaceRunnable}
+ *<br/><br/>
+ * The scheduled job is returned, or null if the operation was run immediately.
+ *
+ * @param runnable the IWorkspaceRunnable to run
+ * @param monitor
+ * @return scheduled job or null if the operation was run immediately
+ */
+ public static Job runWspModification(final IWorkspaceRunnable runnable, IProgressMonitor monitor) {
+ return runWspModification(runnable, ResourcesPlugin.getWorkspace().getRoot(), monitor);
+ }
+
+ /**
+ * Either runs the modification in the current thread (if the workspace is not locked)
+ * or schedules a runnable to perform the operation
+ * @param runnable
+ * @param monitor
+ * @return scheduled job or null if the operation was run immediately
+ */
+ public static Job runWspModification(final IWorkspaceRunnable runnable, final ISchedulingRule rule, IProgressMonitor monitor){
+ if(monitor == null)
+ monitor = new NullProgressMonitor();
+
+ // Should the rule be scheduled, or run immediately
+ boolean scheduleRule = ResourcesPlugin.getWorkspace().isTreeLocked();
+
+ // Check whether current job contains rule 'rule'
+ // If not, we must schedule another job to execute the runnable
+ if (!scheduleRule) {
+ Job currentJob = Job.getJobManager().currentJob();
+ if (currentJob != null && currentJob.getRule() != null && !currentJob.getRule().contains(rule))
+ scheduleRule = true;
+ }
+
+ if(!scheduleRule) {
+ // Run immediately
+ IJobManager mngr = Job.getJobManager();
+ try{
+ mngr.beginRule(rule, monitor);
+ runAtomic(runnable, rule, monitor);
+ } catch (Exception e) {
+ CCorePlugin.log(e);
+ } finally {
+ if(!scheduleRule)
+ monitor.done();
+ mngr.endRule(rule);
+ }
+ } else {
+ // schedule a job for it
+ Job job = new Job(SettingsModelMessages.getString("CProjectDescriptionManager.12")){ //$NON-NLS-1$
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ try {
+ runAtomic(runnable, rule, monitor);
+ } catch (CoreException e) {
+ CCorePlugin.log(e);
+ return e.getStatus();
+ } finally {
+ monitor.done();
+ }
+ return Status.OK_STATUS;
+ }
+ };
+
+ job.setRule(rule);
+ job.setSystem(true);
+ job.schedule();
+ return job;
+ }
+ return null;
+ }
+
+ private static void runAtomic(final IWorkspaceRunnable r, ISchedulingRule rule, IProgressMonitor monitor) throws CoreException{
+ IWorkspace wsp = ResourcesPlugin.getWorkspace();
+ wsp.run(new IWorkspaceRunnable(){
+ public void run(IProgressMonitor monitor) throws CoreException {
+ try {
+ r.run(monitor);
+ } catch (Exception e){
+ CCorePlugin.log(e);
+ throw new CoreException(new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, e.getMessage(), e));
+ }
+ }
+ }, rule, IWorkspace.AVOID_UPDATE, monitor);
+ }
+
+ public void updateProjectDescriptions(IProject[] projects, IProgressMonitor monitor) throws CoreException{
+ if(monitor == null)
+ monitor = new NullProgressMonitor();
+
+ try {
+ IWorkspace wsp = ResourcesPlugin.getWorkspace();
+ if(projects == null)
+ projects = wsp.getRoot().getProjects();
+ final ICProjectDescription dess[] = new ICProjectDescription[projects.length];
+ int num = 0;
+ for(int i = 0; i < projects.length; i++){
+ ICProjectDescription des = getProjectDescription(projects[i], false, true);
+ if(des != null)
+ dess[num++] = des;
+ }
+
+ if(num != 0){
+ final int[] fi = new int[1];
+ fi[0] = num;
+ runWspModification(new IWorkspaceRunnable(){
+
+ public void run(IProgressMonitor monitor) throws CoreException {
+ monitor.beginTask(SettingsModelMessages.getString("CProjectDescriptionManager.13"), fi[0]); //$NON-NLS-1$
+
+ for(int i = 0; i < dess.length; i++){
+ ICProjectDescription des = dess[i];
+ if(des == null)
+ break;
+ IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 1);
+ try {
+ setProjectDescription(des.getProject(), des, true, subMonitor);
+ } catch (CoreException e){
+ CCorePlugin.log(e);
+ } finally {
+ subMonitor.done();
+ }
+ }
+ }
+ }, monitor);
+
+ }
+ } finally {
+ monitor.done();
+ }
+
+ }
+
+ public ICProjectConverter getConverter(IProject project, String oldOwnerId, ICProjectDescription des){
+ CProjectConverterDesciptor[] converterDess = getConverterDescriptors();
+ ICProjectConverter converter = null;
+ for(int i = 0; i < converterDess.length; i++){
+ if(converterDess[i].canConvertProject(project, oldOwnerId, des)){
+ try {
+ converter = converterDess[i].getConverter();
+ } catch (CoreException e) {
+ }
+ if(converter != null)
+ break;
+ }
+ }
+ return converter;
+ }
+
+ private CProjectConverterDesciptor[] getConverterDescriptors(){
+ if(fConverters == null){
+ initConverterInfoSynch();
+ }
+ return fConverters;
+ }
+
+ private synchronized void initConverterInfoSynch(){
+ if(fConverters != null)
+ return;
+
+ IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(CProjectConverterDesciptor.PROJECT_CONVERTER_EXTPOINT_ID);
+ IExtension exts[] = extensionPoint.getExtensions();
+ CProjectConverterDesciptor[] dess = new CProjectConverterDesciptor[exts.length];
+
+ for(int i = 0; i < exts.length; i++){
+ dess[i] = new CProjectConverterDesciptor(exts[i]);
+ }
+
+ fConverters = dess;
+ }
+
+ public ICProjectDescription createProjectDescription(IProject project, boolean loadIfExists) throws CoreException{
+ return createProjectDescription(project, loadIfExists, false);
+ }
+
+ public ICProjectDescription createProjectDescription(IProject project, boolean loadIfExists, boolean creating) throws CoreException{
+ int flags = ICProjectDescriptionManager.GET_WRITABLE | ICProjectDescriptionManager.GET_CREATE_DESCRIPTION;
+ flags |= loadIfExists ? 0 : ICProjectDescriptionManager.GET_EMPTY_PROJECT_DESCRIPTION;
+ flags |= creating ? ICProjectDescriptionManager.PROJECT_CREATING : 0;
+
+ return getProjectDescription(project, flags);
+ }
+
+ public ScannerInfoProviderProxy getScannerInfoProviderProxy(IProject project){
+ ICProjectDescription des = getProjectDescription(project, false);
+ if(des == null){
+ return new ScannerInfoProviderProxy(project);
+ }
+
+ ScannerInfoProviderProxy provider = (ScannerInfoProviderProxy)des.getSessionProperty(SCANNER_INFO_PROVIDER_PROPERTY);
+ if(provider == null){
+ provider = new ScannerInfoProviderProxy(project);
+ des.setSessionProperty(SCANNER_INFO_PROVIDER_PROPERTY, provider);
+ } else {
+ provider.updateProject(project);
+ }
+
+ return provider;
+ }
+
+ public ICProjectDescription getProjectDescription(IProject project){
+ return getProjectDescription(project, true);
+ }
+
+ /*
+ * returns true if the project description was modified false - otherwise
+ */
+ public boolean checkHandleActiveCfgChange(CProjectDescription newDes, ICProjectDescription oldDes, IProjectDescription eDes, IProgressMonitor monitor){
+ if(newDes == null)
+ return false;
+ ICConfigurationDescription newCfg = newDes.getActiveConfiguration();
+ if(newCfg == null)
+ return false;
+
+ ICConfigurationDescription oldCfg = oldDes != null ? oldDes.getActiveConfiguration() : null;
+
+ checkActiveCfgChange(newDes, oldDes);
+ checkSettingCfgChange(newDes, oldDes);
+
+ boolean modified = false;
+
+ try {
+ if(checkBuildSystemChange(eDes, newCfg, oldCfg, monitor))
+ modified = true;
+ } catch (CoreException e) {
+ CCorePlugin.log(e);
+ }
+
+ try {
+ if(checkProjectRefChange(eDes, newCfg, oldCfg, monitor))
+ modified = true;
+ } catch (CoreException e) {
+ CCorePlugin.log(e);
+ }
+
+ return modified;
+ }
+
+// String loadActiveCfgId(ICProjectDescription des){
+// try {
+// return des.getProject().getPersistentProperty(ACTIVE_CFG_PROPERTY);
+// } catch (CoreException e) {
+// CCorePlugin.log(e);
+// }
+// return null;
+// }
+
+ private Collection<IProject> projSetFromProjNameSet(Collection<String> projNames){
+ if(projNames.size() == 0)
+ return new HashSet<IProject>(0);
+
+ Set<IProject> set = new HashSet<IProject>();
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+
+ for (String sproj : projNames)
+ set.add(root.getProject(sproj));
+
+ return set;
+ }
+
+ private boolean checkProjectRefChange(IProjectDescription des, ICConfigurationDescription newCfg, ICConfigurationDescription oldCfg, IProgressMonitor monitor) throws CoreException{
+ if(newCfg == null)
+ return false;
+
+ Map<String, String> oldMap = oldCfg != null ? oldCfg.getReferenceInfo() : null;
+ Map<String, String> newMap = newCfg.getReferenceInfo();
+ Collection<IProject> oldProjSet = oldMap != null ? projSetFromProjNameSet(oldMap.keySet()) : new HashSet<IProject>(0);
+ Collection<IProject> newProjSet = newMap != null ? projSetFromProjNameSet(newMap.keySet()) : new HashSet<IProject>(0);
+
+ Set<IProject> tmp = new HashSet<IProject>(newProjSet);
+ newProjSet.removeAll(oldProjSet);
+ oldProjSet.removeAll(tmp);
+ if(oldProjSet.size() != 0 || newProjSet.size() != 0){
+ IProject[] refs = des.getReferencedProjects();
+ Set<IProject> set = new HashSet<IProject>(Arrays.asList(refs));
+ set.removeAll(oldProjSet);
+ set.addAll(newProjSet);
+ des.setReferencedProjects(set.toArray(new IProject[set.size()]));
+ return true;
+ }
+ return false;
+ }
+
+
+// private void checkBuildSystemChange(IProject project, String newBsId, String oldBsId, IProgressMonitor monitor) throws CoreException{
+// checkBuildSystemChange(project, null, newBsId, oldBsId, monitor);
+// }
+
+ private boolean checkActiveCfgChange(CProjectDescription des,
+ ICProjectDescription oldDes
+// ICConfigurationDescription newCfg,
+// ICConfigurationDescription oldCfg
+ ){
+ ICConfigurationDescription oldCfg = oldDes != null ? oldDes.getActiveConfiguration() : null;
+// String newId = newCfg.getId();
+ String oldId = oldCfg != null ? oldCfg.getId() : null;
+
+
+ return des.checkPersistActiveCfg(oldId, false);
+ }
+
+ private boolean checkSettingCfgChange(CProjectDescription des,
+ ICProjectDescription oldDes
+// ICConfigurationDescription newCfg,
+// ICConfigurationDescription oldCfg
+ ){
+ ICConfigurationDescription oldCfg = oldDes != null ? oldDes.getDefaultSettingConfiguration() : null;
+// String newId = newCfg.getId();
+ String oldId = oldCfg != null ? oldCfg.getId() : null;
+
+
+ return des.checkPersistSettingCfg(oldId, false);
+ }
+
+ private boolean checkBuildSystemChange(IProjectDescription des,
+ ICConfigurationDescription newCfg,
+ ICConfigurationDescription oldCfg,
+ IProgressMonitor monitor) throws CoreException{
+ String newBsId = newCfg != null ? newCfg.getBuildSystemId() : null;
+ String oldBsId = oldCfg != null ? oldCfg.getBuildSystemId() : null;
+
+ CConfigurationDataProviderDescriptor newDr = newBsId != null ? getCfgProviderDescriptor(newBsId) : null;
+ CConfigurationDataProviderDescriptor oldDr = oldBsId != null ? getCfgProviderDescriptor(oldBsId) : null;
+
+ List<String> newNatures, oldNatures, conflictingNatures;
+ newNatures = oldNatures = conflictingNatures = Collections.emptyList();
+ if (oldDr != null)
+ oldNatures = Arrays.asList(oldDr.getNatureIds());
+ if (newDr != null) {
+ newNatures = Arrays.asList(newDr.getNatureIds());
+ conflictingNatures = Arrays.asList(newDr.getConflictingNatureIds());
+ }
+
+ // List of existing natureIds
+ final String[] natureIds = des.getNatureIds();
+
+ // Get the set of items to remove ({oldNatures} - {newNatures}) + conflictingNatures
+ Set<String> toRemove = new HashSet<String>(oldNatures);
+ toRemove.removeAll(newNatures); // Don't remove items we're re-adding
+ toRemove.addAll(conflictingNatures); // Add conflicting natures for removal
+ // Modify an ordered set of the existing natures with the changes
+ final LinkedHashSet<String> cur = new LinkedHashSet<String>(Arrays.asList(natureIds));
+ cur.addAll(newNatures);
+ cur.removeAll(toRemove);
+
+ final String[] newNatureIds = cur.toArray(new String[cur.size()]);
+ if (!Arrays.equals(newNatureIds, natureIds)) {
+ des.setNatureIds(newNatureIds);
+ return true;
+ }
+
+ return false;
+ }
+
+ public void setProjectDescription(IProject project, ICProjectDescription des) throws CoreException {
+ setProjectDescription(project, des, false, null);
+ }
+
+ public void setProjectDescription(IProject project, ICProjectDescription des, boolean force, IProgressMonitor monitor) throws CoreException {
+ int flags = force ? SET_FORCE : 0;
+ setProjectDescription(project, des, flags, monitor);
+ }
+
+ static boolean checkFlags(int flags, int check){
+ return (flags & check) == check;
+ }
+
+ /** ThreadLocal flag to let CDescriptor know whether already in a setProjectDescription */
+ ThreadLocal<Boolean> settingProjectDescription = new ThreadLocal<Boolean>(){@Override protected Boolean initialValue() {return false;}};
+ public void setProjectDescription(IProject project, ICProjectDescription des, int flags, IProgressMonitor monitor) throws CoreException {
+ try {
+ settingProjectDescription.set(true);
+ if(des != null){
+ if (!project.isAccessible())
+ throw ExceptionFactory.createCoreException(MessageFormat.format(CCorePlugin.getResourceString("ProjectDescription.ProjectNotAccessible"), new Object[] {project.getName()})); //$NON-NLS-1$
+
+ if(!des.isValid() && (!fAllowEmptyCreatingDescription || !des.isCdtProjectCreating()))
+ throw ExceptionFactory.createCoreException(SettingsModelMessages.getString("CProjectDescriptionManager.17") + project.getName()); //$NON-NLS-1$
+
+ if(!checkFlags(flags, SET_FORCE) && !des.isModified())
+ return;
+
+ if(((CProjectDescription)des).isLoading()){
+ throw ExceptionFactory.createCoreException("description is being loadded"); //$NON-NLS-1$
+ }
+
+ if(((CProjectDescription)des).isApplying()){
+ throw ExceptionFactory.createCoreException("description is being applied"); //$NON-NLS-1$
+ }
+ }
+ CProjectDescriptionStorageManager.getInstance().setProjectDescription(project, des, flags, monitor);
+ } finally {
+ settingProjectDescription.set(false);
+ }
+ }
+
+ /**
+ * Indicates that a setProjectDescription is currently in progress to prevent recursive setProjectDescription
+ * @return boolean
+ */
+ public boolean isCurrentThreadSetProjectDescription() {
+ return settingProjectDescription.get();
+ }
+
+ private AbstractCProjectDescriptionStorage getProjectDescriptionStorage(IProject project) {
+ return CProjectDescriptionStorageManager.getInstance().getProjectDescriptionStorage(project);
+ }
+
+ /**
+ * Return an ICSettingsStorage based on the provided ICStorageElement
+ * in the given IProject
+ * @param project
+ * @return ICSettingsStorages
+ */
+ public ICSettingsStorage getStorageForElement(IProject project, ICStorageElement element) throws CoreException {
+ if (project != null)
+ return getProjectDescriptionStorage(project).getStorageForElement(element);
+ // project is null means it's a preference element, uses XmlStorages
+ return new XmlStorage((InternalXmlStorageElement)element);
+ }
+
+ private void serializePreference(String key, InternalXmlStorageElement element) throws CoreException{
+ Document doc = element.fElement.getOwnerDocument();
+
+ // Transform the document to something we can save in a file
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ FileOutputStream fileStream = null;
+ try {
+ Transformer transformer = TransformerFactory.newInstance().newTransformer();
+ transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
+ transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
+ DOMSource source = new DOMSource(doc);
+ StreamResult result = new StreamResult(stream);
+ transformer.transform(source, result);
+
+ // Save the document
+ File file = getPreferenceFile(key);
+ String utfString = stream.toString("UTF-8"); //$NON-NLS-1$
+
+ if (file.exists()) {
+// if (projectFile.isReadOnly()) {
+//
+// // Inform Eclipse that we are intending to modify this file
+// // This will provide the user the opportunity, via UI prompts, to fetch the file from source code control
+// // reset a read-only file protection to write etc.
+// // If there is no shell, i.e. shell is null, then there will be no user UI interaction
+//
+// //TODO
+// //IStatus status = projectFile.getWorkspace().validateEdit(new IFile[]{projectFile}, shell);
+//
+// // If the file is still read-only, then we should not attempt the write, since it will
+// // just fail - just throw an exception, to be caught below, and inform the user
+// // For other non-successful status, we take our chances, attempt the write, and pass
+// // along any exception thrown
+//
+// //if (!status.isOK()) {
+// // if (status.getCode() == IResourceStatus.READ_ONLY_LOCAL) {
+// // stream.close();
+// // throw new CoreException(status);
+// //}
+// //}
+// }
+// projectFile.setContents(new ByteArrayInputStream(utfString.getBytes("UTF-8")), IResource.FORCE, new NullProgressMonitor()); //$NON-NLS-1$
+ } else {
+ file.createNewFile();
+ }
+ fileStream = new FileOutputStream(file);
+ byte[] bytes;
+ try {
+ bytes = utfString.getBytes("UTF-8"); //$NON-NLS-1$
+ } catch (UnsupportedEncodingException e){
+ bytes = utfString.getBytes();
+ }
+ fileStream.write(bytes);
+ fileStream.close();
+ // Close the streams
+ stream.close();
+ } catch (TransformerConfigurationException e){
+ throw ExceptionFactory.createCoreException(e);
+ } catch (TransformerException e) {
+ throw ExceptionFactory.createCoreException(e);
+ } catch (IOException e) {
+ throw ExceptionFactory.createCoreException(e);
+ }
+ }
+
+ ICLanguageSetting findLanguagSettingForFile(String fileName, IProject project, ICLanguageSetting settings[]){
+ // if(cType != null){
+ // setting = findLanguageSettingForContentTypeId(cType.getId(), settings, true);
+ // if(setting == null)
+ // setting = findLanguageSettingForContentTypeId(cType.getId(), settings, false);
+ // }
+ ICLanguageSetting setting = null;
+ int index = fileName.lastIndexOf('.');
+ if(index > 0){
+ String ext = fileName.substring(index + 1).trim();
+ if(ext.length() > 0){
+ setting = findLanguageSettingForExtension(ext, settings);
+ }
+ }
+ return setting;
+ }
+
+ public ICLanguageSetting findLanguageSettingForContentTypeId(String id, ICLanguageSetting settings[]/*, boolean src*/){
+ for(int i = 0; i < settings.length; i++){
+ String ids[] = settings[i].getSourceContentTypeIds();
+ if(ListComparator.indexOf(id, ids) != -1)
+ return settings[i];
+ }
+ return null;
+ }
+
+ public ICLanguageSetting[] findCompatibleSettingsForContentTypeId(String id, ICLanguageSetting[] settings/*, boolean src*/){
+ IContentTypeManager manager = Platform.getContentTypeManager();
+ IContentType cType = manager.getContentType(id);
+ if(cType != null){
+ String [] exts = cType.getFileSpecs(IContentType.FILE_EXTENSION_SPEC);
+ if(exts != null && exts.length != 0){
+ List<ICLanguageSetting> list = new ArrayList<ICLanguageSetting>();
+ ICLanguageSetting setting;
+ for(int i = 0; i < exts.length; i++){
+ setting = findLanguageSettingForExtension(exts[i], settings/*, src*/);
+ if(setting != null)
+ list.add(setting);
+ }
+ return list.toArray(new ICLanguageSetting[list.size()]);
+ }
+ }
+ return EMPTY_LANGUAGE_SETTINGS_ARRAY;
+ }
+
+ public ICLanguageSetting findLanguageSettingForExtension(String ext, ICLanguageSetting settings[]/*, boolean src*/){
+ ICLanguageSetting setting;
+ for(int i = 0; i < settings.length; i++){
+ setting = settings[i];
+ String exts[] = setting.getSourceExtensions();
+/* if(src){
+ if(setting.getSourceContentType() == null){
+ exts = setting.getSourceExtensions();
+ }
+ } else {
+ if(setting.getHeaderContentType() == null){
+ exts = setting.getHeaderExtensions();
+ }
+ }
+*/
+ if(exts != null && exts.length != 0){
+ for(int j = 0; j < exts.length; j++){
+ if(ext.equals(exts[j]))
+ return setting;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns a map of configurations elements as discovered from the supplied project
+ * description
+ * @param des
+ * @return Map String -> ICStorageElement: configuration name -> configuration ICStorageElement
+ * @throws CoreException
+ */
+ Map<String, ICStorageElement> createCfgStorages(ICProjectDescription des) throws CoreException{
+ LinkedHashMap<String, ICStorageElement> map = new LinkedHashMap<String, ICStorageElement>();
+ ICStorageElement rootElement = des.getStorage(MODULE_ID, false);
+ if(rootElement != null){
+ ICStorageElement children[] = rootElement.getChildren();
+
+ for(int i = 0; i < children.length; i++){
+ ICStorageElement el = children[i];
+ if(CONFIGURATION.equals(el.getName())){
+ String id = el.getAttribute(CConfigurationSpecSettings.ID);
+ if(id != null)
+ map.put(id, el);
+ }
+ }
+ }
+ return map;
+ }
+
+ /**
+ * Create the configuration storage cfgId in the project description
+ * @param storage the root settingsStorage of the project
+ * @param cfgId the configuration Id desire
+ * @return the cfgId as discovered in the project description or a new ICStorageElement with that Id
+ * @throws CoreException on failure to create storage
+ */
+ ICStorageElement createStorage(ICSettingsStorage storage, String cfgId) throws CoreException {
+ ICStorageElement rootElement = storage.getStorage(MODULE_ID, true); // throws CoreException
+ ICStorageElement children[] = rootElement.getChildren();
+ ICStorageElement element = null;
+
+ for(int i = 0; i < children.length; i++){
+ if(CONFIGURATION.equals(children[i].getName())
+ && cfgId.equals(children[i].getAttribute(CConfigurationSpecSettings.ID))){
+ element = children[i];
+ break;
+ }
+ }
+
+ if(element == null){
+ element = rootElement.createChild(CONFIGURATION);
+ element.setAttribute(CConfigurationSpecSettings.ID, cfgId);
+ }
+
+ return element;
+ }
+
+ /**
+ * Creates a new configuration storage based on an existing 'base' storage.
+ * If a configuration with the new ID already exists in the passed in project storage
+ * a CoreException is thrown.
+ * @param storage the setting storage of the current project description
+ * @param cfgId configID of the new configuration - must be unique in
+ * @param base the base (spec settings) storage element from which settings should be copied.
+ * @return ICStorageElement representing the new configuration
+ * @throws CoreException on failure
+ */
+ ICStorageElement createStorage(ICSettingsStorage storage, String cfgId, ICStorageElement base) throws CoreException{
+ ICStorageElement rootElement = storage.getStorage(MODULE_ID, true);
+ ICStorageElement children[] = rootElement.getChildren();
+ for (ICStorageElement child : children) {
+ if(CONFIGURATION.equals(child.getName())
+ && cfgId.equals(child.getAttribute(CConfigurationSpecSettings.ID)))
+ throw ExceptionFactory.createCoreException(MessageFormat
+ .format(SettingsModelMessages.getString("CProjectDescriptionManager.cfgIDAlreadyExists"), //$NON-NLS-1$
+ new Object[] {cfgId}));
+ }
+ ICStorageElement config = rootElement.importChild(base);
+ config.setAttribute(CConfigurationSpecSettings.ID, cfgId);
+ return config;
+ }
+
+ /**
+ * Remove the storage with the supplied configuration Id from the project
+ * @param storage The root settingsStorage of the project
+ * @param cfgId the configuration ID which would be
+ * @throws CoreException
+ */
+ void removeStorage(ICSettingsStorage storage, String cfgId) throws CoreException{
+ ICStorageElement rootElement = storage.getStorage(MODULE_ID, false);
+ if(rootElement != null){
+ ICStorageElement children[] = rootElement.getChildren();
+
+ for(int i = 0; i < children.length; i++){
+ if(CONFIGURATION.equals(children[i].getName())
+ && cfgId.equals(children[i].getAttribute(CConfigurationSpecSettings.ID))){
+ rootElement.removeChild(children[i]);
+ break;
+ }
+ }
+ }
+ }
+
+ CConfigurationData loadData(ICConfigurationDescription des, IProgressMonitor monitor) throws CoreException{
+ if(monitor == null)
+ monitor = new NullProgressMonitor();
+
+ CConfigurationDataProvider provider = getProvider(des);
+ return provider.loadConfiguration(des, monitor);
+ }
+
+ CConfigurationData applyData(CConfigurationDescriptionCache des, ICConfigurationDescription baseDescription, CConfigurationData base, SettingsContext context, IProgressMonitor monitor) throws CoreException {
+ if(monitor == null)
+ monitor = new NullProgressMonitor();
+
+ CConfigurationDataProvider provider = getProvider(des);
+ context.init(des);
+ return provider.applyConfiguration(des, baseDescription, base, context, monitor);
+ }
+
+ void notifyCached(ICConfigurationDescription des, CConfigurationData data, IProgressMonitor monitor) {
+ if(monitor == null)
+ monitor = new NullProgressMonitor();
+
+ try {
+ CConfigurationDataProvider provider = getProvider(des);
+ provider.dataCached(des, data, monitor);
+ } catch (CoreException e){
+ CCorePlugin.log(e);
+ }
+ }
+
+ void removeData(ICConfigurationDescription des, CConfigurationData data, IProgressMonitor monitor) throws CoreException{
+ if(monitor == null)
+ monitor = new NullProgressMonitor();
+
+ CConfigurationDataProvider provider = getProvider(des);
+ provider.removeConfiguration(des, data, monitor);
+ }
+
+ CConfigurationData createData(ICConfigurationDescription des, ICConfigurationDescription baseDescription, CConfigurationData base, boolean clone, IProgressMonitor monitor) throws CoreException{
+ if(monitor == null)
+ monitor = new NullProgressMonitor();
+
+ CConfigurationDataProvider provider = getProvider(des);
+ return provider.createConfiguration(des, baseDescription, base, clone, monitor);
+ }
+
+ private CConfigurationDataProvider getProvider(ICConfigurationDescription des) throws CoreException{
+ CConfigurationDataProviderDescriptor providerDes = getCfgProviderDescriptor(des);
+ if(providerDes == null)
+ throw ExceptionFactory.createCoreException(SettingsModelMessages.getString("CProjectDescriptionManager.1")); //$NON-NLS-1$
+
+ return providerDes.getProvider();
+ }
+
+ private CConfigurationDataProviderDescriptor getCfgProviderDescriptor(ICConfigurationDescription des){
+ return getCfgProviderDescriptor(des.getBuildSystemId());
+ }
+
+ private CConfigurationDataProviderDescriptor getCfgProviderDescriptor(String id){
+ initProviderInfo();
+ return fProviderMap.get(id);
+ }
+
+ private void initProviderInfo(){
+ if(fProviderMap != null)
+ return;
+
+ synchronized (this) {
+ if(fProviderMap != null)
+ return;
+
+ IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(CConfigurationDataProviderDescriptor.DATA_PROVIDER_EXTPOINT_ID);
+ IExtension exts[] = extensionPoint.getExtensions();
+ fProviderMap = new HashMap<String, CConfigurationDataProviderDescriptor>(exts.length);
+
+ for(int i = 0; i < exts.length; i++){
+ CConfigurationDataProviderDescriptor des = new CConfigurationDataProviderDescriptor(exts[i]);
+ fProviderMap.put(des.getId(), des);
+ }
+ }
+ }
+
+/* CConfigurationSpecSettings createConfigurationSpecSettings(ICConfigurationDescription cfg) throws CoreException{
+ CConfigurationSpecSettings settings = null;
+ if(cfg instanceof CConfigurationDescriptionCache){
+ settings = new CConfigurationSpecSettings(cfg, createStorage(cfg.getProjectDescription(), cfg.getId()));
+ } else {
+ ICProjectDescription des = getProjecDescription(cfg.getProjectDescription().getProject(), false);
+ CConfigurationDescriptionCache cache = (CConfigurationDescriptionCache)des.getConfigurationById(cfg.getId());
+ if(cache != null){
+ settings = new CConfigurationSpecSettings(cfg, cache.getSpecSettings());
+ } else {
+ settings = new CConfigurationSpecSettings(cfg, createStorage(cfg.getProjectDescription(), cfg.getId()));
+ }
+ }
+ return settings;
+ }
+*/
+
+ public ICStorageElement createPreferenceStorage(String key, boolean createEmptyIfNotFound, boolean readOnly) throws CoreException{
+ try {
+ DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ Document doc = null;
+ Element element = null;
+ InputStream stream = null;
+
+ try{
+ stream = getPreferenceProperty(key);
+ if(stream != null){
+ doc = builder.parse(stream);
+
+ // Get the first element in the project file
+ Node rootElement = doc.getFirstChild();
+
+ if (rootElement.getNodeType() != Node.PROCESSING_INSTRUCTION_NODE) {
+ throw ExceptionFactory.createCoreException(SettingsModelMessages.getString("CProjectDescriptionManager.2")); //$NON-NLS-1$
+ } else {
+ String fileVersion = rootElement.getNodeValue();
+ Version version = new Version(fileVersion);
+ // Make sure that the version is compatible with the manager
+ // Version must between min version and current version inclusive
+ if (MIN_DESCRIPTION_VERSION.compareTo(version) > 0 || DESCRIPTION_VERSION.compareTo(version) < 0) {
+ throw ExceptionFactory.createCoreException(SettingsModelMessages.getString("CProjectDescriptionManager.3")); //$NON-NLS-1$
+ }
+ }
+
+ // Now get the project root element (there should be only one)
+ NodeList nodes = doc.getElementsByTagName(ROOT_PREFERENCE_ELEMENT);
+ if (nodes.getLength() == 0)
+ throw ExceptionFactory.createCoreException(SettingsModelMessages.getString("CProjectDescriptionManager.4")); //$NON-NLS-1$
+ Node node = nodes.item(0);
+ if(node.getNodeType() != Node.ELEMENT_NODE)
+ throw ExceptionFactory.createCoreException(SettingsModelMessages.getString("CProjectDescriptionManager.5")); //$NON-NLS-1$
+ element = (Element)node;
+ } else if(!createEmptyIfNotFound){
+ throw ExceptionFactory.createCoreException(SettingsModelMessages.getString("CProjectDescriptionManager.6")); //$NON-NLS-1$
+ }
+ } catch (FactoryConfigurationError e) {
+ if(!createEmptyIfNotFound)
+ throw ExceptionFactory.createCoreException(e.getLocalizedMessage());
+ } catch (SAXException e) {
+ if(!createEmptyIfNotFound)
+ throw ExceptionFactory.createCoreException(e);
+ } catch (IOException e) {
+ if(!createEmptyIfNotFound)
+ throw ExceptionFactory.createCoreException(e);
+ } finally {
+ if(stream != null){
+ try {
+ stream.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ if(element == null) {
+ doc = builder.newDocument();
+ ProcessingInstruction instruction = doc.createProcessingInstruction(VERSION_ELEMENT_NAME, DESCRIPTION_VERSION.toString());
+ doc.appendChild(instruction);
+ element = doc.createElement(ROOT_PREFERENCE_ELEMENT);
+ doc.appendChild(element);
+ }
+ return new InternalXmlStorageElement(element, null, false, readOnly);
+ } catch (ParserConfigurationException e) {
+ throw ExceptionFactory.createCoreException(e);
+ }
+ }
+
+ private InputStream getPreferenceProperty(String key) {
+ InputStream stream = null;
+ File file = getPreferenceFile(key);
+ if (file.exists()) {
+ try {
+ stream = new FileInputStream(file);
+ } catch (FileNotFoundException e) {
+ CCorePlugin.log(e);
+ }
+ }
+ return stream;
+ }
+
+ private File getPreferenceFile(String key){
+ IPath path = CCorePlugin.getDefault().getStateLocation();
+ path = path.append(key);
+ return path.toFile();
+ }
+
+ public static File toLocalFile(URI uri, IProgressMonitor monitor) throws CoreException {
+ IFileStore fileStore = EFS.getStore(uri);
+ File localFile = fileStore.toLocalFile(EFS.NONE, monitor);
+ if (localFile ==null)
+ // non local file system
+ localFile= fileStore.toLocalFile(EFS.CACHE, monitor);
+ return localFile;
+ }
+
+ ICDescriptionDelta createDelta(ICProjectDescription newDescription, ICProjectDescription oldDescription){
+ CProjectDescriptionDelta delta = new CProjectDescriptionDelta(newDescription, oldDescription);
+
+ if(delta.getDeltaKind() == ICDescriptionDelta.CHANGED){
+ ICConfigurationDescription[] cfgs = newDescription.getConfigurations();
+ for(int i = 0; i < cfgs.length; i++){
+ ICConfigurationDescription oldCfg = oldDescription.getConfigurationById(cfgs[i].getId());
+ CProjectDescriptionDelta cfgDelta = createDelta(cfgs[i], oldCfg);
+ if(cfgDelta != null){
+ delta.addChild(cfgDelta);
+ }
+ }
+
+ cfgs = oldDescription.getConfigurations();
+ for(int i = 0; i < cfgs.length; i++){
+ ICConfigurationDescription newCfg = newDescription.getConfigurationById(cfgs[i].getId());
+ if(newCfg == null)
+ delta.addChild(createDelta(null, cfgs[i]));
+ }
+
+ if(checkCfgChange(newDescription, oldDescription, true))
+ delta.addChangeFlags(ICDescriptionDelta.ACTIVE_CFG);
+
+ if(checkCfgChange(newDescription, oldDescription, false))
+ delta.addChangeFlags(ICDescriptionDelta.INDEX_CFG);
+
+ if(oldDescription.isCdtProjectCreating() && !newDescription.isCdtProjectCreating())
+ delta.addChangeFlags(ICDescriptionDelta.PROJECT_CREAION_COMPLETED);
+ }
+ return delta.isEmpty() ? null : delta;
+ }
+
+ private boolean checkCfgChange(ICProjectDescription newDes, ICProjectDescription oldDes, boolean active){
+ ICConfigurationDescription newCfg, oldCfg;
+
+ if(active){
+ newCfg = newDes.getActiveConfiguration();
+ oldCfg = oldDes.getActiveConfiguration();
+ } else {
+ newCfg = newDes.getDefaultSettingConfiguration();
+ oldCfg = oldDes.getDefaultSettingConfiguration();
+ }
+
+ if(newCfg == null){
+ return oldCfg != null;
+ } else if (oldCfg == null){
+ return true;
+ }
+ return !newCfg.getId().equals(oldCfg.getId());
+ }
+
+/* void postProcessNewDescriptionCache(CProjectDescription des, ICProjectDescriptionDelta delta){
+ if(delta == null && delta.getDeltaKind() != ICProjectDescriptionDelta.CHANGED)
+ return;
+
+ ICConfigurationDescription indexCfg = des.getIndexConfiguration();
+ ICConfigurationDescription activeCfg = des.getActiveConfiguration();
+ ICProjectDescriptionDelta activeCfgDelta = findDelta(activeCfg.getId(), delta);
+ if(indexCfg != activeCfg){
+ switch(activeCfgDelta.getDeltaKind()){
+ case ICProjectDescriptionDelta.CHANGED:
+ des.setIndexConfiguration(activeCfg);
+ }
+ }
+
+
+ }
+*/
+ private ICDescriptionDelta findDelta(String id, ICDescriptionDelta delta){
+ ICDescriptionDelta children[] = delta.getChildren();
+ ICSettingObject obj;
+ for(int i = 0; i < children.length; i++){
+ obj = children[i].getSetting();
+ if(obj.getId().equals(id))
+ return children[i];
+ }
+ return null;
+ }
+
+ public int calculateDescriptorFlags(ICConfigurationDescription newCfg, ICConfigurationDescription oldCfg){
+ try {
+ int flags = 0;
+ CConfigurationSpecSettings newSettings = ((IInternalCCfgInfo)newCfg).getSpecSettings();
+ CConfigurationSpecSettings oldSettings = ((IInternalCCfgInfo)oldCfg).getSpecSettings();
+ String newId = newSettings.getCOwnerId();
+ String oldId = oldSettings.getCOwnerId();
+ if(!CDataUtil.objectsEqual(newId, oldId))
+ flags |= ICDescriptionDelta.OWNER;
+
+ Map<String, CConfigExtensionReference[]> newMap = newSettings.getExtensionMapCopy();
+ Map<String, CConfigExtensionReference[]> oldMap = oldSettings.getExtensionMapCopy();
+
+ for(Iterator<Map.Entry<String, CConfigExtensionReference[]>> iter = newMap.entrySet().iterator(); iter.hasNext();){
+ Map.Entry entry = iter.next();
+ iter.remove();
+ CConfigExtensionReference[] oldRefs = oldMap.remove(entry.getKey());
+ if(oldRefs == null){
+ flags |= ICDescriptionDelta.EXT_REF;
+ break;
+ }
+
+ CConfigExtensionReference[] newRefs = (CConfigExtensionReference[])entry.getValue();
+ if(newRefs.length != oldRefs.length){
+ flags |= ICDescriptionDelta.EXT_REF;
+ break;
+ }
+
+ Set<CConfigExtensionReference> newSet = new HashSet<CConfigExtensionReference>(Arrays.asList(newRefs));
+ Set<CConfigExtensionReference> oldSet = new HashSet<CConfigExtensionReference>(Arrays.asList(oldRefs));
+ if(newSet.size() != oldSet.size()){
+ flags |= ICDescriptionDelta.EXT_REF;
+ break;
+ }
+
+ newSet.removeAll(oldSet);
+ if(newSet.size() != 0){
+ flags |= ICDescriptionDelta.EXT_REF;
+ break;
+ }
+ }
+
+ return flags;
+ } catch (CoreException e) {
+ CCorePlugin.log(e);
+ }
+ return 0;
+ }
+
+ public CProjectDescriptionDelta createDelta(ICConfigurationDescription newCfg, ICConfigurationDescription oldCfg){
+ CProjectDescriptionDelta delta = new CProjectDescriptionDelta(newCfg, oldCfg);
+ IInternalCCfgInfo newInfo = (IInternalCCfgInfo)newCfg;
+ IInternalCCfgInfo oldInfo = (IInternalCCfgInfo)oldCfg;
+ if(delta.getDeltaKind() == ICDescriptionDelta.CHANGED){
+ ICFolderDescription[] foDess = newCfg.getFolderDescriptions();
+ for(int i = 0; i < foDess.length; i++){
+ ICResourceDescription oldDes = oldCfg.getResourceDescription(foDess[i].getPath(), true);
+ if(oldDes != null && oldDes.getType() == ICSettingBase.SETTING_FOLDER){
+ CProjectDescriptionDelta foDelta = createDelta(foDess[i], (ICFolderDescription)oldDes);
+ if(foDelta != null)
+ delta.addChild(foDelta);
+ } else {
+ delta.addChild(createDelta(foDess[i], null));
+ }
+ }
+
+ foDess = oldCfg.getFolderDescriptions();
+ for(int i = 0; i < foDess.length; i++){
+ ICResourceDescription newDes = newCfg.getResourceDescription(foDess[i].getPath(), true);
+ if(newDes == null || newDes.getType() != ICSettingBase.SETTING_FOLDER){
+ delta.addChild(createDelta(null, foDess[i]));
+ }
+ }
+
+ ICFileDescription[] fiDess = newCfg.getFileDescriptions();
+ for(int i = 0; i < fiDess.length; i++){
+ ICResourceDescription oldDes = oldCfg.getResourceDescription(fiDess[i].getPath(), true);
+ if(oldDes != null && oldDes.getType() == ICSettingBase.SETTING_FILE){
+ CProjectDescriptionDelta fiDelta = createDelta(fiDess[i], (ICFileDescription)oldDes);
+ if(fiDelta != null)
+ delta.addChild(fiDelta);
+ } else {
+ delta.addChild(createDelta(fiDess[i], null));
+ }
+ }
+
+ fiDess = oldCfg.getFileDescriptions();
+ for(int i = 0; i < fiDess.length; i++){
+ ICResourceDescription newDes = newCfg.getResourceDescription(fiDess[i].getPath(), true);
+ if(newDes == null || newDes.getType() != ICSettingBase.SETTING_FILE){
+ delta.addChild(createDelta(null, fiDess[i]));
+ }
+ }
+
+ CProjectDescriptionDelta tpsDelta = createDelta(newCfg.getTargetPlatformSetting(), oldCfg.getTargetPlatformSetting());
+ if(tpsDelta != null)
+ delta.addChild(tpsDelta);
+
+ if(!newCfg.getName().equals(oldCfg.getName())){
+ delta.addChangeFlags(ICDescriptionDelta.NAME);
+ }
+
+ ICSourceEntry newEntries[] = newCfg.getSourceEntries();
+ ICSourceEntry oldEntries[] = oldCfg.getSourceEntries();
+
+ if(newEntries.length > oldEntries.length){
+ delta.addChangeFlags(ICDescriptionDelta.SOURCE_ADDED);
+ } else {
+ ICSourceEntry newEntry;
+ for(int i = 0; i < newEntries.length; i++){
+ boolean found = false;
+ newEntry = newEntries[i];
+ for(int j = 0; j < oldEntries.length; j++){
+ if(newEntry.equals(oldEntries[j])){
+ found = true;
+ break;
+ }
+ }
+
+ if(!found){
+ delta.addChangeFlags(ICDescriptionDelta.SOURCE_ADDED);
+ break;
+ }
+ }
+ }
+
+ if(oldEntries.length > newEntries.length){
+ delta.addChangeFlags(ICDescriptionDelta.SOURCE_REMOVED);
+ } else {
+ ICSourceEntry oldEntry;
+ for(int i = 0; i < oldEntries.length; i++){
+ boolean found = false;
+ oldEntry = oldEntries[i];
+ for(int j = 0; j < newEntries.length; j++){
+ if(oldEntry.equals(newEntries[j])){
+ found = true;
+ break;
+ }
+ }
+
+ if(!found){
+ delta.addChangeFlags(ICDescriptionDelta.SOURCE_REMOVED);
+ break;
+ }
+ }
+ }
+
+ try {
+ CConfigurationSpecSettings newSettings = newInfo.getSpecSettings();
+ CConfigurationSpecSettings oldSettings = oldInfo.getSpecSettings();
+ if(!newSettings.extRefSettingsEqual(oldSettings))
+ delta.addChangeFlags(ICDescriptionDelta.EXT_REF);
+ } catch (CoreException e){
+ CCorePlugin.log(e);
+ }
+
+
+ calculateCfgExtSettingsDelta(delta);
+
+ int drFlags = calculateDescriptorFlags(newCfg, oldCfg);
+ if(drFlags != 0)
+ delta.addChangeFlags(drFlags);
+ }
+
+ return delta.isEmpty() ? null : delta;
+ }
+
+ private void calculateCfgExtSettingsDelta(CProjectDescriptionDelta delta){
+ ICConfigurationDescription newDes = (ICConfigurationDescription)delta.getNewSetting();
+ ICConfigurationDescription oldDes = (ICConfigurationDescription)delta.getOldSetting();
+ ExtSettingsDelta[] deltas = getSettingChange(newDes, oldDes);
+ int flags = 0;
+ int addedRemoved = ICDescriptionDelta.EXTERNAL_SETTINGS_ADDED | ICDescriptionDelta.EXTERNAL_SETTINGS_REMOVED;
+ if(deltas != null ){
+ for(int i = 0; i < deltas.length; i++){
+ ICSettingEntry[][] d = deltas[i].getEntriesDelta();
+ if(d[0] != null)
+ flags |= ICDescriptionDelta.EXTERNAL_SETTINGS_ADDED;
+ if(d[1] != null)
+ flags |= ICDescriptionDelta.EXTERNAL_SETTINGS_REMOVED;
+
+ if((flags & (addedRemoved)) == addedRemoved)
+ break;
+ }
+// delta.setExtSettingsDeltas(deltas);
+ if(flags != 0)
+ delta.addChangeFlags(flags);
+ }
+
+ int cfgRefFlags = calcRefChangeFlags(newDes, oldDes);
+ if(cfgRefFlags != 0)
+ delta.addChangeFlags(cfgRefFlags);
+ }
+
+ private int calcRefChangeFlags(ICConfigurationDescription newDes, ICConfigurationDescription oldDes){
+ Map<String, String> newMap = newDes != null ? newDes.getReferenceInfo() : null;
+ Map<String, String> oldMap = oldDes != null ? oldDes.getReferenceInfo() : null;
+
+ int flags = 0;
+ if(newMap == null || newMap.size() == 0){
+ if(oldMap != null && oldMap.size() != 0){
+ flags = ICDescriptionDelta.CFG_REF_REMOVED;
+ }
+ } else {
+ if(oldMap == null || oldMap.size() == 0){
+ flags = ICDescriptionDelta.CFG_REF_ADDED;
+ } else {
+ boolean stop = false;
+ for(Iterator iter = newMap.entrySet().iterator(); iter.hasNext();){
+ Map.Entry newEntry = (Map.Entry)iter.next();
+ Object newProj = newEntry.getKey();
+ Object newCfg = newEntry.getValue();
+ Object oldCfg = oldMap.remove(newProj);
+ if(!newCfg.equals(oldCfg)){
+ flags |= ICDescriptionDelta.CFG_REF_ADDED;
+ if(oldCfg != null){
+ flags |= ICDescriptionDelta.CFG_REF_REMOVED;
+ stop = true;
+ }
+ if(stop)
+ break;
+ }
+ }
+
+ if(!oldMap.isEmpty())
+ flags |= ICDescriptionDelta.CFG_REF_REMOVED;
+ }
+ }
+
+ return flags;
+ }
+
+
+ private ExtSettingsDelta[] getSettingChange(ICConfigurationDescription newDes, ICConfigurationDescription oldDes){
+ CExternalSetting[] newSettings = newDes != null ? (CExternalSetting[])newDes.getExternalSettings() : null;
+ CExternalSetting[] oldSettings = oldDes != null ? (CExternalSetting[])oldDes.getExternalSettings() : null;
+ return CExternalSettinsDeltaCalculator.getInstance().getSettingChange(newSettings, oldSettings);
+ }
+
+ private CProjectDescriptionDelta createDelta(ICFolderDescription newFo, ICFolderDescription oldFo){
+ CProjectDescriptionDelta delta = new CProjectDescriptionDelta(newFo, oldFo);
+
+ if(delta.getDeltaKind() == ICDescriptionDelta.CHANGED){
+ ICLanguageSetting newLss[] = newFo.getLanguageSettings();
+ ICLanguageSetting oldLss[] = oldFo.getLanguageSettings();
+ List<ICLanguageSetting> newList = new ArrayList<ICLanguageSetting>(Arrays.asList(newLss));
+ List<ICLanguageSetting> oldList = new ArrayList<ICLanguageSetting>(Arrays.asList(oldLss));
+ List<ICLanguageSetting[]> matched = sortSettings(newList, oldList);
+
+ for(Iterator<ICLanguageSetting[]> iter = matched.iterator(); iter.hasNext();){
+ ICLanguageSetting[] match = iter.next();
+ CProjectDescriptionDelta lsDelta = createDelta(match[0], match[1]);
+ if(lsDelta != null)
+ delta.addChild(lsDelta);
+ }
+
+ for(Iterator<ICLanguageSetting> iter = newList.iterator(); iter.hasNext();){
+ ICLanguageSetting added = iter.next();
+ delta.addChild(createDelta(added, null));
+ }
+
+ for(Iterator<ICLanguageSetting> iter = oldList.iterator(); iter.hasNext();){
+ ICLanguageSetting removed = iter.next();
+ delta.addChild(createDelta(null, removed));
+ }
+
+// HashMap oldMap = new HashMap();
+// for(int i = 0; i < oldLss.length; i++){
+// oldMap.put(oldLss[i].getId(), oldLss[i]);
+// }
+
+// for(int i = 0; i < newLss.length; i++){
+// ICLanguageSetting oldLs = (ICLanguageSetting)oldMap.remove(newLss[i].getId());
+// CProjectDescriptionDelta lsDelta = createDelta(newLss[i], oldLs);
+// if(lsDelta != null)
+// delta.addChild(lsDelta);
+// }
+
+// if(!oldMap.isEmpty()){
+// for(Iterator iter = oldMap.values().iterator(); iter.hasNext();){
+// delta.addChild(createDelta(null, (ICLanguageSetting)iter.next()));
+// }
+// }
+
+// if(!newFo.getPath().equals(oldFo.getPath()))
+// delta.addChangeFlags(ICProjectDescriptionDelta.PATH);
+
+ if(newFo.isExcluded() != oldFo.isExcluded())
+ delta.addChangeFlags(ICDescriptionDelta.EXCLUDE);
+ }
+
+ return delta.isEmpty() ? null : delta;
+ }
+
+ private List<ICLanguageSetting[]> sortSettings(List<ICLanguageSetting> settings1,
+ List<ICLanguageSetting> settings2){
+ ICLanguageSetting setting1;
+ ICLanguageSetting setting2;
+ List<ICLanguageSetting[]> result = new ArrayList<ICLanguageSetting[]>();
+ for(Iterator<ICLanguageSetting> iter1 = settings1.iterator(); iter1.hasNext();){
+ setting1 = iter1.next();
+ for(Iterator<ICLanguageSetting> iter2 = settings2.iterator(); iter2.hasNext();){
+ setting2 = iter2.next();
+
+ if(setting2.getId().equals(setting1.getId())){
+ iter1.remove();
+ iter2.remove();
+ ICLanguageSetting [] match = new ICLanguageSetting[2];
+ match[0] = setting1;
+ match[1] = setting2;
+ result.add(match);
+ break;
+ }
+ }
+ }
+
+ for(Iterator<ICLanguageSetting> iter1 = settings1.iterator(); iter1.hasNext();){
+ setting1 = iter1.next();
+ String lId = setting1.getLanguageId();
+ if(lId != null){
+ for(Iterator<ICLanguageSetting> iter2 = settings2.iterator(); iter2.hasNext();){
+ setting2 = iter2.next();
+
+ if(lId.equals(setting2.getLanguageId())){
+ iter1.remove();
+ iter2.remove();
+ ICLanguageSetting [] match = new ICLanguageSetting[2];
+ match[0] = setting1;
+ match[1] = setting2;
+ result.add(match);
+ break;
+ }
+ }
+ }
+ }
+
+ for(Iterator<ICLanguageSetting> iter1 = settings1.iterator(); iter1.hasNext();){
+ setting1 = iter1.next();
+ String cTypeIds1[] = setting1.getSourceContentTypeIds();
+ if(cTypeIds1.length != 0){
+ for(Iterator<ICLanguageSetting> iter2 = settings2.iterator(); iter2.hasNext();){
+ setting2 = iter2.next();
+ if(Arrays.equals(cTypeIds1, setting2.getSourceContentTypeIds())){
+ iter1.remove();
+ iter2.remove();
+ ICLanguageSetting [] match = new ICLanguageSetting[2];
+ match[0] = setting1;
+ match[1] = setting2;
+ result.add(match);
+ break;
+ }
+ }
+ }
+ }
+
+ for(Iterator<ICLanguageSetting> iter1 = settings1.iterator(); iter1.hasNext();){
+ setting1 = iter1.next();
+ if(setting1.getSourceContentTypeIds().length == 0){
+ String srcExts[] = setting1.getSourceExtensions();
+ if(srcExts.length != 0){
+ for(Iterator<ICLanguageSetting> iter2 = settings2.iterator(); iter2.hasNext();){
+ setting2 = iter2.next();
+ if(setting2.getSourceContentTypeIds().length == 0){
+ if(Arrays.equals(srcExts, setting2.getSourceExtensions())){
+ iter1.remove();
+ iter2.remove();
+ ICLanguageSetting [] match = new ICLanguageSetting[2];
+ match[0] = setting1;
+ match[1] = setting2;
+ result.add(match);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ private CProjectDescriptionDelta createDelta(ICFileDescription newFi, ICFileDescription oldFi){
+ CProjectDescriptionDelta delta = new CProjectDescriptionDelta(newFi, oldFi);
+
+ if(delta.getDeltaKind() == ICDescriptionDelta.CHANGED){
+ CProjectDescriptionDelta lsDelta = createDelta(newFi.getLanguageSetting(), oldFi.getLanguageSetting());
+ if(lsDelta != null)
+ delta.addChild(lsDelta);
+
+// if(!newFi.getPath().equals(oldFi.getPath()))
+// delta.addChangeFlags(ICProjectDescriptionDelta.PATH);
+
+ if(newFi.isExcluded() != oldFi.isExcluded())
+ delta.addChangeFlags(ICDescriptionDelta.EXCLUDE);
+ }
+
+ return delta.isEmpty() ? null : delta;
+ }
+
+ private CProjectDescriptionDelta createDelta(ICLanguageSetting newLs, ICLanguageSetting oldLs){
+ CProjectDescriptionDelta delta = new CProjectDescriptionDelta(newLs, oldLs);
+
+ if(delta.getDeltaKind() == ICDescriptionDelta.CHANGED){
+ int kinds[] = KindBasedStore.getLanguageEntryKinds();
+ int kind;
+ int addedKinds = 0;
+ int removedKinds = 0;
+ int reorderedKinds = 0;
+ for(int i = 0; i < kinds.length; i++){
+ kind = kinds[i];
+ ICLanguageSettingEntry newEntries[] = newLs.getSettingEntries(kind);
+ ICLanguageSettingEntry oldEntries[] = oldLs.getSettingEntries(kind);
+ boolean[] change = calculateSettingsChanges(newEntries, oldEntries);
+
+ if(change[0])
+ addedKinds |= kind;
+ if(change[1])
+ removedKinds |= kind;
+ if(change[2])
+ reorderedKinds |= kind;
+ }
+ delta.setAddedLanguageEntriesKinds(addedKinds);
+ delta.setRemovedLanguageEntriesKinds(removedKinds);
+ delta.setReorderedLanguageEntriesKinds(reorderedKinds);
+
+ String[] newCtIds = newLs.getSourceContentTypeIds();
+ String[] oldCtIds = oldLs.getSourceContentTypeIds();
+
+ if(!Arrays.equals(newCtIds, oldCtIds))
+ delta.addChangeFlags(ICDescriptionDelta.SOURCE_CONTENT_TYPE);
+
+
+ String[] newExts = newLs.getSourceExtensions();
+ String[] oldExts = oldLs.getSourceExtensions();
+ if(!Arrays.equals(newExts, oldExts))
+ delta.addChangeFlags(ICDescriptionDelta.SOURCE_ENTENSIONS);
+
+
+// newCt = newLs.getHeaderContentType();
+// oldCt = oldLs.getHeaderContentType();
+
+// if(!compare(newCt, oldCt))
+// delta.addChangeFlags(ICDescriptionDelta.HEADER_CONTENT_TYPE);
+
+// newExts = newLs.getHeaderExtensions();
+// oldExts = oldLs.getHeaderExtensions();
+// if(!Arrays.equals(newExts, oldExts))
+// delta.addChangeFlags(ICDescriptionDelta.HEADER_ENTENSIONS);
+ }
+
+ return delta.isEmpty() ? null : delta;
+ }
+
+ private boolean[] calculateSettingsChanges(ICLanguageSettingEntry newEntries[], ICLanguageSettingEntry oldEntries[]) {
+ boolean result[] = new boolean[3];
+
+ // if nothing was known before do not generate any deltas.
+ if (oldEntries == null) {
+ return result;
+ }
+ // Sanity checks
+ if (newEntries == null) {
+ newEntries = EMPTY_LANGUAGE_SETTINGS_ENTRIES_ARRAY;
+ }
+
+ // Check the removed entries.
+ for (int i = 0; i < oldEntries.length; i++) {
+ boolean found = false;
+ for (int j = 0; j < newEntries.length; j++) {
+ if (oldEntries[i].equals(newEntries[j])) {
+ found = true;
+ break;
+ }
+ }
+ if(!found){
+ result[1] = true;
+ break;
+ }
+ }
+
+ // Check the new entries.
+ for (int i = 0; i < newEntries.length; i++) {
+ boolean found = false;
+ for (int j = 0; j < oldEntries.length; j++) {
+ if (newEntries[i].equals(oldEntries[j])) {
+ found = true;
+ break;
+ }
+ }
+ if(!found){
+ result[0] = true;
+ break;
+ }
+ }
+
+ // Check for reorder
+ if (!result[0] && !result[1] && oldEntries.length == newEntries.length) {
+ for (int i = 0; i < newEntries.length; i++) {
+ if (!newEntries[i].equals(oldEntries[i])) {
+ result[2] = true;
+ break;
+ }
+ }
+ }
+ // They may have remove some duplications, catch here .. consider it as reordering.
+ if (!result[0] && !result[1] && oldEntries.length != newEntries.length) {
+ result[2] = true;
+ }
+
+ return result;
+ }
+
+/* public boolean entriesEqual(ICLanguageSettingEntry entries1[], ICLanguageSettingEntry entries2[]){
+ if(entries1.length != entries2.length)
+ return false;
+
+ for(int i = 0; i < entries1.length; i++){
+ if(!entries1[i].equals(entries2[i]))
+ return false;
+ }
+
+ return true;
+ }
+*/
+ private CProjectDescriptionDelta createDelta(ICTargetPlatformSetting newTPS, ICTargetPlatformSetting oldTPS){
+ CProjectDescriptionDelta delta = new CProjectDescriptionDelta(newTPS, oldTPS);
+ if(!Arrays.equals(newTPS.getBinaryParserIds(), oldTPS.getBinaryParserIds()))
+ delta.addChangeFlags(ICDescriptionDelta.BINARY_PARSER_IDS);
+
+ return delta.isEmpty() ? null : delta;
+ }
+
+ ICElementDelta[] generateCElementDeltas(ICProject cProject, ICDescriptionDelta projDesDelta){
+ if(projDesDelta == null)
+ return EMPTY_CELEMENT_DELTA;
+
+ int kind = projDesDelta.getDeltaKind();
+ switch(kind){
+ case ICDescriptionDelta.CHANGED:
+ ICProjectDescription newDes = (ICProjectDescription)projDesDelta.getNewSetting();
+ ICProjectDescription oldDes = (ICProjectDescription)projDesDelta.getOldSetting();
+// int flags = projDesDelta.getChangeFlags();
+// ICConfigurationDescription activeCfg = newDes.getActiveConfiguration();
+ ICConfigurationDescription indexCfg = newDes.getDefaultSettingConfiguration();
+// if(indexCfg != activeCfg){
+// ICDescriptionDelta delta = findDelta(activeCfg.getId(), projDesDelta);
+// if(delta != null && delta.getDeltaKind() == ICDescriptionDelta.CHANGED){
+// indexCfg = activeCfg;
+// newDes.setIndexConfiguration(activeCfg);
+// }
+// }
+ ICConfigurationDescription oldIndexCfg = oldDes.getDefaultSettingConfiguration();
+ ICDescriptionDelta indexDelta;
+ if(oldIndexCfg != null && oldIndexCfg.getId().equals(indexCfg.getId())){
+ indexDelta = findDelta(indexCfg.getId(), projDesDelta);
+ } else {
+ indexDelta = createDelta(indexCfg, oldIndexCfg);
+ }
+ if(indexDelta != null){
+ List<CElementDelta> list = new ArrayList<CElementDelta>();
+ generateCElementDeltasFromCfgDelta(cProject, indexDelta, list);
+ return list.toArray(new ICElementDelta[list.size()]);
+ }
+ return EMPTY_CELEMENT_DELTA;
+ case ICDescriptionDelta.ADDED:
+ case ICDescriptionDelta.REMOVED:
+ break;
+ }
+ return EMPTY_CELEMENT_DELTA;
+ }
+
+ private List<CElementDelta> generateCElementDeltasFromCfgDelta(ICProject cProject, ICDescriptionDelta cfgDelta, List<CElementDelta> list){
+ int kind = cfgDelta.getDeltaKind();
+ switch(kind){
+ case ICDescriptionDelta.CHANGED:
+ int descriptionFlags = cfgDelta.getChangeFlags();
+ int celementFlags = 0;
+ if((descriptionFlags & ICDescriptionDelta.SOURCE_ADDED) != 0)
+ celementFlags |= ICElementDelta.F_ADDED_PATHENTRY_SOURCE;
+ if((descriptionFlags & ICDescriptionDelta.SOURCE_REMOVED) != 0)
+ celementFlags |= ICElementDelta.F_REMOVED_PATHENTRY_SOURCE;
+
+ if(celementFlags != 0){
+ CElementDelta cElDelta = new CElementDelta(cProject.getCModel());
+ cElDelta.changed(cProject, celementFlags);
+ list.add(cElDelta);
+ }
+
+ ICDescriptionDelta children[] = cfgDelta.getChildren();
+ ICDescriptionDelta child;
+ int type;
+ for(int i = 0; i < children.length; i++){
+ child = children[i];
+ type = child.getSettingType();
+ if(type == ICSettingBase.SETTING_FILE || type == ICSettingBase.SETTING_FOLDER){
+ generateCElementDeltasFromResourceDelta(cProject, child, list);
+ }
+ }
+ case ICDescriptionDelta.ADDED:
+ case ICDescriptionDelta.REMOVED:
+ break;
+ }
+ return list;
+ }
+
+ private List<CElementDelta> generateCElementDeltasFromResourceDelta(ICProject cProject, ICDescriptionDelta delta, List<CElementDelta> list){
+ int kind = delta.getDeltaKind();
+ ICDescriptionDelta parentDelta = delta.getParent();
+ ICElement el;
+// IProject project = cProject.getProject();
+ IResource rc = null;
+
+ ICResourceDescription oldRcDes;
+ ICResourceDescription newRcDes;
+ IPath path;
+ switch(kind){
+ case ICDescriptionDelta.REMOVED:
+ oldRcDes = (ICResourceDescription)delta.getOldSetting();
+ path = oldRcDes.getPath();
+ newRcDes = ((ICConfigurationDescription)parentDelta.getNewSetting()).getResourceDescription(path, false);
+ break;
+ case ICDescriptionDelta.CHANGED:
+// if((delta.getChangeFlags() & ICProjectDescriptionDelta.PATH) == 0){
+ newRcDes = (ICResourceDescription)delta.getNewSetting();
+ path = newRcDes.getPath();
+ oldRcDes = (ICResourceDescription)delta.getOldSetting();
+ break;
+// }
+ //if path changed treat as added
+ case ICDescriptionDelta.ADDED:
+ default:
+ newRcDes = (ICResourceDescription)delta.getNewSetting();
+ path = newRcDes.getPath();
+ oldRcDes = ((ICConfigurationDescription)parentDelta.getOldSetting()).getResourceDescription(path, false);
+ break;
+ }
+ path = path.makeRelative();
+ el = null;
+ try {
+ el = cProject.findElement(path);
+ rc = el.getResource();
+ } catch (CModelException e) {
+// int i = 0;
+ }
+// rc = ResourcesPlugin.getWorkspace().getRoot().findMember(project.getFullPath().append(path));
+ if(rc != null){
+ if(rc.getType() == IResource.FILE){
+ String fileName = path.lastSegment();
+ ICLanguageSetting newLS = getLanguageSetting(newRcDes, fileName);
+ ICLanguageSetting oldLS = getLanguageSetting(oldRcDes, fileName);
+ ICDescriptionDelta ld = createDelta(newLS, oldLS);
+ generateCElementDeltasFromLanguageDelta(el, ld, list);
+ } else {
+ if(newRcDes.getType() == ICSettingBase.SETTING_FOLDER){
+ ICFolderDescription oldFoDes = null;
+ if (oldRcDes != null) {
+ if (oldRcDes.getType() == ICSettingBase.SETTING_FOLDER)
+ oldFoDes = (ICFolderDescription)oldRcDes;
+ }
+ ICDescriptionDelta folderDelta = createDelta((ICFolderDescription)newRcDes, oldFoDes);
+ if(folderDelta != null){
+ ICDescriptionDelta children[] = folderDelta.getChildren();
+ ICDescriptionDelta child;
+ for(int i = 0; i < children.length; i++){
+ child = children[i];
+ if(child.getSettingType() == ICSettingBase.SETTING_LANGUAGE){
+ generateCElementDeltasFromLanguageDelta(el, child, list);
+ }
+ }
+ }
+ } else {
+ //ERROR?
+ }
+
+ }
+ }
+ return list;
+ }
+
+ private ICLanguageSetting getLanguageSetting(ICResourceDescription rcDes, String fileName){
+ if(rcDes.getType() == ICSettingBase.SETTING_FILE){
+ return ((ICFileDescription)rcDes).getLanguageSetting();
+ }
+ return ((ICFolderDescription)rcDes).getLanguageSettingForFile(fileName);
+ }
+
+ private List<CElementDelta> generateCElementDeltasFromLanguageDelta(ICElement el, ICDescriptionDelta delta, List<CElementDelta> list){
+ if(delta == null)
+ return list;
+
+ int flags = 0;
+ flags |= calculateEntriesFlags(delta.getAddedEntriesKinds(), true);
+ flags |= calculateEntriesFlags(delta.getRemovedEntriesKinds(), false);
+ flags |= calculateEntriesFlags(delta.getReorderedEntriesKinds(), true);
+ if(flags != 0){
+ CElementDelta cElDelta = new CElementDelta(el.getCModel());
+ cElDelta.changed(el, flags);
+ list.add(cElDelta);
+ }
+ return list;
+ }
+
+ private int calculateEntriesFlags(int languageDeltaKinds, boolean added){
+ int flags = 0;
+ int kindsArray[] = kindsToArray(languageDeltaKinds);
+
+ for(int i = 0; i < kindsArray.length; i++){
+ switch(kindsArray[i]){
+ case ICLanguageSettingEntry.INCLUDE_PATH:
+ flags |= ICElementDelta.F_CHANGED_PATHENTRY_INCLUDE;
+ break;
+ case ICLanguageSettingEntry.INCLUDE_FILE:
+ flags |= ICElementDelta.F_CHANGED_PATHENTRY_INCLUDE;
+ break;
+ case ICLanguageSettingEntry.MACRO:
+ flags |= ICElementDelta.F_CHANGED_PATHENTRY_MACRO;
+ break;
+ case ICLanguageSettingEntry.MACRO_FILE:
+ flags |= ICElementDelta.F_CHANGED_PATHENTRY_MACRO;
+ break;
+ case ICLanguageSettingEntry.LIBRARY_PATH:
+ flags |= added ? ICElementDelta.F_ADDED_PATHENTRY_LIBRARY
+ : ICElementDelta.F_REMOVED_PATHENTRY_LIBRARY;
+ break;
+ case ICLanguageSettingEntry.LIBRARY_FILE:
+ flags |= added ? ICElementDelta.F_ADDED_PATHENTRY_LIBRARY
+ : ICElementDelta.F_REMOVED_PATHENTRY_LIBRARY;
+ break;
+ }
+ }
+ return flags;
+ }
+
+ int[] kindsToArray(int kinds){
+ int allKinds[] = KindBasedStore.getLanguageEntryKinds();
+ int kindsArray[] = new int[allKinds.length];
+ int num = 0;
+ for(int i = 0; i < allKinds.length; i++){
+ if((allKinds[i] & kinds) != 0){
+ kindsArray[num++] = allKinds[i];
+ }
+ }
+
+ if(num < allKinds.length){
+ int tmp[] = new int[num];
+ if(num > 0)
+ System.arraycopy(kindsArray, 0, tmp, 0, num);
+ kindsArray = tmp;
+ }
+ return kindsArray;
+ }
+
+ /*
+ * Methods for manipulating the set of project description listeners
+ */
+
+ public void addCProjectDescriptionListener(ICProjectDescriptionListener listener, int eventTypes) {
+ fListeners.add(new ListenerDescriptor(listener, eventTypes));
+ }
+
+ public void removeCProjectDescriptionListener(ICProjectDescriptionListener listener) {
+ fListeners.remove(listener);
+ }
+
+ public void notifyListeners(CProjectDescriptionEvent event){
+ int eventType = event.getEventType();
+ for (ListenerDescriptor listener : fListeners) {
+ if (listener.handlesEvent(eventType))
+ listener.fListener.handleEvent(event);
+ }
+ }
+
+ void checkRemovedConfigurations(ICDescriptionDelta delta){
+ if(delta == null)
+ return;
+
+ ICDescriptionDelta cfgDeltas[] = delta.getChildren();
+ for(int i = 0; i < cfgDeltas.length; i++){
+ if(cfgDeltas[i].getDeltaKind() == ICDescriptionDelta.REMOVED){
+ CConfigurationDescriptionCache des = (CConfigurationDescriptionCache)cfgDeltas[i].getOldSetting();
+ CConfigurationData data = des.getConfigurationData();
+ try {
+ removeData(des, data, null);
+ } catch (CoreException e) {
+ }
+ }
+ }
+ }
+
+ public ICConfigurationDescription getPreferenceConfiguration(String buildSystemId) throws CoreException {
+ return getPreferenceConfiguration(buildSystemId, true);
+ }
+
+ private void runContextOperations(SettingsContext context, IProgressMonitor monitor){
+ IWorkspaceRunnable toRun = context.createOperationRunnable();
+ if(toRun != null){
+ runWspModification(toRun, monitor);
+ } else if (monitor != null){
+ monitor.done();
+ }
+ }
+
+ public ICConfigurationDescription getPreferenceConfiguration(String buildSystemId, boolean write) throws CoreException {
+ ICConfigurationDescription des = getLoaddedPreference(buildSystemId);
+ if(des == null){
+ try {
+ des = loadPreference(buildSystemId);
+ } catch (CoreException e) {
+ // CCorePlugin.log(e);
+ }
+
+ if(des == null){
+ try {
+ des = createNewPreference(buildSystemId);
+ } catch (CoreException e) {
+ CCorePlugin.log(e);
+ }
+ }
+
+ setLoaddedPreference(buildSystemId, (CConfigurationDescriptionCache)des);
+ }
+ if(des != null && write){
+ try {
+ des = createWritablePreference((CConfigurationDescriptionCache)des);
+ } catch (CoreException e) {
+ CCorePlugin.log(e);
+ }
+ }
+ return des;
+ }
+
+ public void setPreferenceConfiguration(String buildSystemId, ICConfigurationDescription des) throws CoreException{
+ if(!needSavePreference(buildSystemId, des))
+ return;
+
+ CConfigurationDescriptionCache cache = createPreferenceCache(des);
+
+ savePreferenceConfiguration(buildSystemId, cache);
+
+ setLoaddedPreference(buildSystemId, cache);
+ }
+
+ private void savePreferenceConfiguration(String buildStystemId, CConfigurationDescriptionCache cache) throws CoreException{
+ ICStorageElement el = cache.getSpecSettings().getRootStorageElement();
+ saveBuildSystemConfigPreferenceStorage(buildStystemId, el);
+ }
+
+ private void saveBuildSystemConfigPreferenceStorage(String buildSystemId, ICStorageElement el) throws CoreException{
+ ICStorageElement cur = getBuildSystemConfigPreferenceStorage(buildSystemId);
+ ICStorageElement parent = cur.getParent();
+ parent.removeChild(cur);
+ parent.importChild(el);
+ savePreferenceStorage(PREFERENCES_STORAGE, MODULE_ID, parent);
+ }
+
+ private boolean needSavePreference(String buildSystemId, ICConfigurationDescription des){
+ if(des.isModified()
+ || !des.isPreferenceConfiguration()
+ || !des.getBuildSystemId().equals(buildSystemId))
+ return true;
+
+ return false;
+ }
+
+ private ICConfigurationDescription createWritablePreference(CConfigurationDescriptionCache cache) throws CoreException{
+ return new CConfigurationDescription(cache, fPrefUpdater);
+ }
+
+ private CConfigurationDescriptionCache createPreferenceCache(ICConfigurationDescription des) throws CoreException{
+ IInternalCCfgInfo cfgDes = (IInternalCCfgInfo)des;
+ CConfigurationData baseData = cfgDes.getConfigurationData(false);
+ CConfigurationDescriptionCache baseCache = null;
+ if(baseData instanceof CConfigurationDescriptionCache){
+ baseCache = (CConfigurationDescriptionCache)baseData;
+ baseData = baseCache.getConfigurationData();
+ }
+ CConfigurationSpecSettings settings = cfgDes.getSpecSettings();
+ ICStorageElement rootEl = getBuildSystemConfigPreferenceStorage(des.getBuildSystemId(), true, false);
+ ICStorageElement rootParent = rootEl.getParent();
+ rootParent.removeChild(rootEl);
+ ICStorageElement baseRootEl = settings.getRootStorageElement();
+ rootEl = rootParent.importChild(baseRootEl);
+ CConfigurationDescriptionCache cache = new CConfigurationDescriptionCache(des, baseData, baseCache, cfgDes.getSpecSettings(), null, rootEl);
+ CSettingEntryFactory factory = new CSettingEntryFactory();
+ SettingsContext context = new SettingsContext(null);
+ cache.applyData(factory, context);
+ cache.doneInitialization();
+ factory.clear();
+ runContextOperations(context, null);
+ return cache;
+ }
+
+ private ICConfigurationDescription createNewPreference(String buildSystemId) throws CoreException {
+ ICStorageElement cfgEl = getBuildSystemConfigPreferenceStorage(buildSystemId, true, false);
+
+ String id = PREFERENCE_CFG_ID_PREFIX + buildSystemId;
+ CConfigurationDescription des = new CConfigurationDescription(id, PREFERENCE_CFG_NAME, buildSystemId, cfgEl, fPrefUpdater);
+
+ return createPreferenceCache(des);
+ }
+
+// private XmlStorage createBuildSystemCfgPrefStore() throws CoreException{
+// ICStorageElement el = getPreferenceStorage(PREFERENCES_STORAGE, MODULE_ID, true, false);
+//
+// XmlStorage store = new XmlStorage((InternalXmlStorageElement)el);
+//
+// return store;
+// }
+//
+// ICSettingsStorage getBuildSystemCfgPrefStore() throws CoreException{
+// if(fPrefCfgStorage == null){
+// fPrefCfgStorage = createBuildSystemCfgPrefStore();
+// }
+//
+// return copyStorage(fPrefCfgStorage, false);
+// }
+
+ ICStorageElement getBuildSystemConfigPreferenceStorage(String buildSystemId) throws CoreException{
+ return getBuildSystemConfigPreferenceStorage(buildSystemId, true, false);
+ }
+
+ private ICStorageElement getBuildSystemConfigPreferenceStorage(String buildSystemId, boolean createIfNotDound, boolean readOnly) throws CoreException{
+ ICStorageElement el = getPreferenceStorage(PREFERENCES_STORAGE, MODULE_ID, createIfNotDound, readOnly);
+ ICStorageElement cfgEl = null;
+
+ if(el != null){
+ ICStorageElement children[] = el.getChildren();
+ for(int i = 0; i < children.length; i++){
+ ICStorageElement child = children[i];
+ if(PREFERENCE_BUILD_SYSTEM_ELEMENT.equals(child.getName())){
+ if(buildSystemId.equals(child.getAttribute(ID))){
+ cfgEl = child;
+ break;
+ }
+ }
+
+ }
+
+ if(cfgEl == null){
+ cfgEl = el.createChild(PREFERENCE_BUILD_SYSTEM_ELEMENT);
+ cfgEl.setAttribute(ID, buildSystemId);
+ }
+
+ }
+
+ return cfgEl;
+ }
+
+ private ICConfigurationDescription loadPreference(String buildSystemId) throws CoreException{
+ ICStorageElement el = getPreferenceStorage(PREFERENCES_STORAGE, MODULE_ID, false, false);
+
+ ICStorageElement children[] = el.getChildren();
+ ICStorageElement cfgEl = null;
+ for(int i = 0; i < children.length; i++){
+ ICStorageElement child = children[i];
+ if(PREFERENCE_BUILD_SYSTEM_ELEMENT.equals(child.getName())){
+ if(buildSystemId.equals(child.getAttribute(ID))){
+ cfgEl = child;
+ break;
+ }
+ }
+
+ }
+ CConfigurationDescriptionCache cache = new CConfigurationDescriptionCache(cfgEl, null);
+ CSettingEntryFactory factory = new CSettingEntryFactory();
+ cache.loadData(factory);
+ cache.doneInitialization();
+ factory.clear();
+ return cache;
+ }
+
+ public ICStorageElement getPreferenceStorage(String prefKey, String storageId, boolean createIfNotDound, boolean readOnly) throws CoreException{
+ XmlStorage store = getPreferenceStore(prefKey, createIfNotDound, readOnly);
+
+ return store.getStorage(storageId, createIfNotDound);
+ }
+
+ private XmlStorage getPreferenceStore(String prefKey, boolean createIfNotDound, boolean readOnly) throws CoreException{
+ ICStorageElement el = createPreferenceStorage(prefKey, createIfNotDound, readOnly);
+
+ XmlStorage store = new XmlStorage((InternalXmlStorageElement)el);
+
+ return store;
+ }
+
+ public void savePreferenceStorage(String prefKey, String storageId, ICStorageElement el) throws CoreException{
+ XmlStorage store = getPreferenceStore(prefKey, true, false);
+ store.importStorage(storageId, el);
+
+ InternalXmlStorageElement rootEl = new InternalXmlStorageElement(store.fElement, store.isReadOnly());
+ serializePreference(prefKey, rootEl);
+ }
+
+ private CConfigurationDescriptionCache getLoaddedPreference(String buildSystemId){
+ return fPreferenceMap.get(buildSystemId);
+ }
+
+ private void setLoaddedPreference(String buildSystemId, CConfigurationDescriptionCache des){
+ fPreferenceMap.put(buildSystemId, des);
+ }
+
+ public CConfigBasedDescriptorManager getDescriptorManager(){
+ return fDescriptorManager;
+ }
+
+ public CConfigurationData createDefaultConfigData(IProject project, CDataFactory factory) throws CoreException{
+ return createDefaultConfigData(project, CDataUtil.genId(DEFAULT_CFG_ID_PREFIX), DEFAULT_CFG_NAME, factory);
+ }
+
+ public CConfigurationData createDefaultConfigData(IProject project, String id, String name, CDataFactory factory) throws CoreException{
+ if(factory == null)
+ factory = new CDataFactory();
+
+ CConfigurationData data = CDataUtil.createEmptyData(id, name, factory, true);
+// CDataUtil.
+//// data.initEmptyData();
+//
+// CDataUtil.adjustConfig(data, factory);
+
+ factory.setModified(data, false);
+ return data;
+ }
+
+ public boolean isNewStyleIndexCfg(IProject project){
+ ICProjectDescription des = getProjectDescription(project, false);
+ if(des != null)
+ return isNewStyleIndexCfg(des);
+ return false;
+ }
+
+ public boolean isNewStyleIndexCfg(ICProjectDescription des){
+ ICConfigurationDescription cfgDes = des.getDefaultSettingConfiguration();
+ if(cfgDes != null)
+ return isNewStyleCfg(cfgDes);
+ return false;
+ }
+
+ public boolean isNewStyleProject(IProject project){
+ return isNewStyleProject(getProjectDescription(project, false));
+ }
+
+ public boolean isNewStyleProject(ICProjectDescription des){
+ if(des == null)
+ return false;
+
+ return isNewStyleIndexCfg(des);
+ }
+
+ public boolean isNewStyleCfg(ICConfigurationDescription cfgDes){
+ if(cfgDes == null)
+ return false;
+
+ CConfigurationData data = ((IInternalCCfgInfo)cfgDes).getConfigurationData(false);
+ if(data instanceof CConfigurationDescriptionCache){
+ data = ((CConfigurationDescriptionCache)data).getConfigurationData();
+ }
+
+ return data != null && !PathEntryConfigurationDataProvider.isPathEntryData(data);
+ }
+
+// public String[] getContentTypeFileSpecs (IProject project, IContentType type) {
+// String[] globalSpecs = type.getFileSpecs(IContentType.FILE_EXTENSION_SPEC);
+// IContentTypeSettings settings = null;
+// if (project != null) {
+// IScopeContext projectScope = new ProjectScope(project);
+// try {
+// settings = type.getSettings(projectScope);
+// } catch (Exception e) {}
+// if (settings != null) {
+// String[] specs = settings.getFileSpecs(IContentType.FILE_EXTENSION_SPEC);
+// if (specs.length > 0) {
+// int total = globalSpecs.length + specs.length;
+// String[] projSpecs = new String[total];
+// int i=0;
+// for (int j=0; j<specs.length; j++) {
+// projSpecs[i] = specs[j];
+// i++;
+// }
+// for (int j=0; j<globalSpecs.length; j++) {
+// projSpecs[i] = globalSpecs[j];
+// i++;
+// }
+// return projSpecs;
+// }
+// }
+// }
+// return globalSpecs;
+// }
+
+// public String[] getExtensionsFromContentTypes(IProject project, String[] typeIds){
+// return CDataUtil.getExtensionsFromContentTypes(project, typeIds);
+// }
+
+ static ICLanguageSetting getLanguageSettingForFile(ICConfigurationDescription cfgDes, IPath path, boolean ignoreExcludeStatus){
+ int segCount = path.segmentCount();
+ if(segCount == 0)
+ return null;
+
+ ICResourceDescription rcDes = cfgDes.getResourceDescription(path, false);
+ if(rcDes == null || (!ignoreExcludeStatus && rcDes.isExcluded()))
+ return null;
+
+ if(rcDes.getType() == ICSettingBase.SETTING_FOLDER){
+ return ((ICFolderDescription)rcDes).getLanguageSettingForFile(path.lastSegment());
+ }
+ return ((ICFileDescription)rcDes).getLanguageSetting();
+ }
+
+ static private HashMap<HashSet<String>, CLanguageData> createExtSetToLDataMap(IProject project, CLanguageData[] lDatas){
+ HashMap<HashSet<String>, CLanguageData> map = new HashMap<HashSet<String>, CLanguageData>();
+
+ for(int i = 0; i < lDatas.length; i++){
+ CLanguageData lData = lDatas[i];
+ String[] exts = CDataUtil.getSourceExtensions(project, lData);
+ HashSet<String> set = new HashSet<String>(Arrays.asList(exts));
+ map.put(set, lData);
+ }
+
+ return map;
+ }
+
+ static boolean removeNonCustomSettings(IProject project, CConfigurationData data){
+ PathSettingsContainer cr = CDataUtil.createRcDataHolder(data);
+ PathSettingsContainer[] crs = cr.getChildren(false);
+ PathSettingsContainer child, parent;
+ CResourceData childRcData;
+ boolean modified = false;
+ for(int i = 0; i < crs.length; i++){
+ child = crs[i];
+ childRcData = (CResourceData)child.getValue();
+ if(childRcData.getType() == ICSettingBase.SETTING_FOLDER){
+ CResourceData parentRcData = null;
+ for(parent = child.getParentContainer();
+ (parentRcData = (CResourceData)parent.getValue()).getType() != ICSettingBase.SETTING_FOLDER;
+ parent = parent.getParentContainer());
+ if(!settingsCustomized(project, (CFolderData)parentRcData, (CFolderData)childRcData)){
+ try {
+ data.removeResourceData(childRcData);
+ child.remove();
+ modified = true;
+ } catch (CoreException e) {
+ CCorePlugin.log(e);
+ }
+ }
+ } else {
+ parent = child.getParentContainer();
+ if(!settingsCustomized(project, (CResourceData)parent.getValue(), (CFileData)childRcData)){
+ try {
+ data.removeResourceData(childRcData);
+ child.remove();
+ modified = true;
+ } catch (CoreException e) {
+ CCorePlugin.log(e);
+ }
+ }
+ }
+
+ }
+ return modified;
+ }
+
+ static boolean settingsCustomized(IProject project, CFolderData parent, CFolderData child){
+ if(baseSettingsCustomized(parent, child))
+ return true;
+
+ CLanguageData[] childLDatas = child.getLanguageDatas();
+ CLanguageData[] parentLDatas = parent.getLanguageDatas();
+
+ if(childLDatas.length != parentLDatas.length)
+ return true;
+
+ if(childLDatas.length != 0){
+ HashMap<HashSet<String>, CLanguageData> parentMap = createExtSetToLDataMap(project, parentLDatas);
+ HashMap<HashSet<String>, CLanguageData> childMap = createExtSetToLDataMap(project, childLDatas);
+ CLanguageData parentLData, childLData;
+ for(Iterator iter = parentMap.entrySet().iterator(); iter.hasNext();){
+ Map.Entry entry = (Map.Entry)iter.next();
+ childLData = childMap.get(entry.getKey());
+ if(childLData == null)
+ return true;
+
+ parentLData = (CLanguageData)entry.getValue();
+ if(!langDatasEqual(parentLData, childLData))
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ static boolean settingsCustomized(IProject project, CResourceData parent, CFileData child){
+ if(baseSettingsCustomized(parent, child))
+ return true;
+
+ CLanguageData lData = child.getLanguageData();
+
+ if(parent.getType() == ICSettingBase.SETTING_FOLDER){
+ CFolderData foParent = (CFolderData)parent;
+
+ IPath childPath = child.getPath();
+ String fileName = childPath.lastSegment();
+ if(PatternNameMap.isPatternName(fileName))
+ return true;
+
+ CLanguageData parentLangData = CDataUtil.findLanguagDataForFile(fileName, project, foParent);
+
+ return !langDatasEqual(lData, parentLangData);
+ }
+
+ CFileData fiParent = (CFileData)parent;
+ CLanguageData parentLangData = fiParent.getLanguageData();
+ return !langDatasEqual(lData, parentLangData);
+ }
+
+ static boolean langDatasEqual(CLanguageData lData1, CLanguageData lData2){
+ if(lData1 == null)
+ return lData2 == null;
+
+ if(lData2 == null)
+ return false;
+
+ int kinds[] = KindBasedStore.getLanguageEntryKinds();
+ int kind;
+ for(int i = 0; i < kinds.length; i++){
+ kind = kinds[i];
+ ICLanguageSettingEntry entries1[] = lData1.getEntries(kind);
+ ICLanguageSettingEntry entries2[] = lData2.getEntries(kind);
+ if(!Arrays.equals(entries1, entries2))
+ return false;
+ }
+
+ return true;
+ }
+
+ private static boolean baseSettingsCustomized(CResourceData parent, CResourceData child){
+// if(parent.isExcluded() != child.isExcluded())
+// return true;
+
+ if(child.hasCustomSettings())
+ return true;
+
+ return false;
+ }
+
+
+ public ICProjectDescriptionWorkspacePreferences getProjectDescriptionWorkspacePreferences(
+ boolean write) {
+ if(fPreferences == null){
+ try {
+ fPreferences = loadPreferences();
+ } catch (CoreException e) {
+ }
+ if(fPreferences == null)
+ fPreferences = new CProjectDescriptionWorkspacePreferences((ICStorageElement)null, null, true);
+ }
+
+ CProjectDescriptionWorkspacePreferences prefs = fPreferences;
+
+ if(write)
+ prefs = new CProjectDescriptionWorkspacePreferences(prefs, false);
+
+ return prefs;
+ }
+
+ public boolean setProjectDescriptionWorkspacePreferences(ICProjectDescriptionWorkspacePreferences prefs,
+ boolean updateProjects,
+ IProgressMonitor monitor) {
+ if(monitor == null)
+ monitor = new NullProgressMonitor();
+ boolean changed = false;
+ ICProjectDescriptionWorkspacePreferences oldPrefs = getProjectDescriptionWorkspacePreferences(false);
+ try {
+ do {
+ if(oldPrefs != prefs){
+ if(prefs.getConfigurationRelations() != oldPrefs.getConfigurationRelations()){
+ changed = true;
+ break;
+ }
+ }
+ } while(false);
+
+ if(changed){
+ CProjectDescriptionWorkspacePreferences basePrefs;
+ if(prefs instanceof CProjectDescriptionWorkspacePreferences)
+ basePrefs = (CProjectDescriptionWorkspacePreferences)prefs;
+ else
+ throw new IllegalArgumentException();
+
+ fPreferences = new CProjectDescriptionWorkspacePreferences(basePrefs, null, true);
+
+ storePreferences(fPreferences);
+
+ if(updateProjects)
+ updateProjectDescriptions(null, monitor);
+ }
+ } catch (CoreException e) {
+ CCorePlugin.log(e);
+ } finally {
+ monitor.done();
+ }
+
+ return changed;
+ }
+
+ private void storePreferences(CProjectDescriptionWorkspacePreferences prefs) throws CoreException {
+ ICStorageElement el = getCProjectDescriptionPreferencesElement(true, false);
+ prefs.serialize(el);
+ saveCProjectDescriptionPreferencesElement(el);
+ }
+
+ private void saveCProjectDescriptionPreferencesElement(ICStorageElement el) throws CoreException{
+ ICStorageElement cur = getCProjectDescriptionPreferencesElement(true, false);
+ ICStorageElement parent = cur.getParent();
+ parent.removeChild(cur);
+ parent.importChild(el);
+ savePreferenceStorage(PREFERENCES_STORAGE, MODULE_ID, parent);
+ }
+
+ private CProjectDescriptionWorkspacePreferences loadPreferences() throws CoreException{
+ ICStorageElement el = getCProjectDescriptionPreferencesElement(false, true);
+ return new CProjectDescriptionWorkspacePreferences(el, null, true);
+ }
+
+ private ICStorageElement getCProjectDescriptionPreferencesElement(boolean createIfNotFound, boolean readOnly) throws CoreException{
+ ICStorageElement el = getPreferenceStorage(PREFERENCES_STORAGE, MODULE_ID, createIfNotFound, readOnly);
+ ICStorageElement[] children = el.getChildren();
+ for(int i = 0; i < children.length; i++){
+ if(PREFERENCES_ELEMENT.equals(children[i].getName()))
+ return children[i];
+ }
+ if(createIfNotFound)
+ return el.createChild(PREFERENCES_ELEMENT);
+ throw ExceptionFactory.createCoreException(SettingsModelMessages.getString("CProjectDescriptionManager.14")); //$NON-NLS-1$
+ }
+
+ public void updateExternalSettingsProviders(String[] ids, IProgressMonitor monitor){
+ ExtensionContainerFactory.updateReferencedProviderIds(ids, monitor);
+ }
+
+ boolean isEmptyCreatingDescriptionAllowed(){
+ return fAllowEmptyCreatingDescription;
+ }
+
+ void setEmptyCreatingDescriptionAllowed(boolean allow){
+ fAllowEmptyCreatingDescription = allow;
+ }
+
+}