/******************************************************************************* * Copyright (c) 2006, 2007 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 *******************************************************************************/ package org.eclipse.cdt.managedbuilder.internal.core; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import java.util.Set; import org.eclipse.cdt.managedbuilder.core.IBuildObject; import org.eclipse.cdt.managedbuilder.core.IBuilder; import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; import org.eclipse.cdt.managedbuilder.core.IManagedProject; import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; import org.eclipse.cdt.managedbuilder.core.IResourceInfo; import org.eclipse.cdt.managedbuilder.core.ITool; import org.eclipse.cdt.managedbuilder.core.IToolChain; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ProjectScope; import org.eclipse.core.runtime.preferences.InstanceScope; import org.osgi.service.prefs.BackingStoreException; import org.osgi.service.prefs.Preferences; /** * This class allows specifying BuildObject-specific persisted properties * */ public class PropertyManager { // private static final String PROPS_PROPERTY = "properties"; //$NON-NLS-1$ // private static final QualifiedName propsSessionProperty = new QualifiedName(ManagedBuilderCorePlugin.getUniqueIdentifier(), PROPS_PROPERTY); private static final String NODE_NAME = "properties"; //$NON-NLS-1$ private static PropertyManager fInstance; private LoaddedInfo fLoaddedInfo; private static class LoaddedInfo { private final IProject fProject; private final String fCfgId; // one of Map<String, String> or Map<String, Map<String, Properties>> private final Map<String, Object> fCfgPropertyMap; LoaddedInfo(IProject project, String cfgId, Map<String, Object> cfgPropertyMap){ fProject = project; fCfgId = cfgId; fCfgPropertyMap = cfgPropertyMap; } public IConfiguration getConfiguration(){ return PropertyManager.getConfigurationFromId(fProject, fCfgId); } public IProject getProject(){ return fProject; } public String getConfigurationId(){ return fCfgId; } public Map<String, Object> getProperties(){ return fCfgPropertyMap; } public boolean cfgMatch(IConfiguration cfg){ if(fCfgId == null || fProject == null) return false; if(!fCfgId.equals(cfg.getId())) return false; if(!fProject.equals(PropertyManager.getProject(cfg))) return false; return true; } } private PropertyManager(){ } public static PropertyManager getInstance(){ if(fInstance == null) fInstance = new PropertyManager(); return fInstance; } protected void setProperty(IConfiguration cfg, IBuildObject bo, String prop, String value){ if(((Configuration)cfg).isPreference()) return; Properties props = getProperties(cfg, bo); if(props != null){ props.setProperty(prop, value); } } protected String getProperty(IConfiguration cfg, IBuildObject bo, String prop){ if(((Configuration)cfg).isPreference()) return null; Properties props = getProperties(cfg, bo); if(props != null) return props.getProperty(prop); return null; } protected Properties getProperties(IConfiguration cfg, IBuildObject bo){ return loadProperties(cfg, bo); } private LoaddedInfo getLoaddedInfo(){ return fLoaddedInfo; } private synchronized void setLoaddedInfo(LoaddedInfo info){ fLoaddedInfo = info; } protected Map<String, Object> getLoaddedData(IConfiguration cfg){ LoaddedInfo info = getLoaddedInfo(); if(info == null) return null; if(!info.cfgMatch(cfg)) return null; return info.getProperties(); // Map map = null; // IProject proj = null; // try { // if(!((Configuration)cfg).isPreference()){ // proj = cfg.getOwner().getProject(); // map = (Map)proj.getSessionProperty(propsSessionProperty); // } // if(map == null){ // map = new HashMap(); // if(proj != null){ // proj.setSessionProperty(propsSessionProperty, map); // } // } // map = (Map)map.get(cfg.getId()); // } catch (CoreException e) { // } // return map; } protected synchronized void clearLoaddedData(IConfiguration cfg){ if(((Configuration)cfg).isPreference()) return; LoaddedInfo info = getLoaddedInfo(); if(info == null) return; if(info.cfgMatch(cfg)) setLoaddedInfo(null); // IProject proj = cfg.getOwner().getProject(); // try { // proj.setSessionProperty(propsSessionProperty, null); // } catch (CoreException e) { // } } private static IProject getProject(IConfiguration cfg){ IResource rc = cfg.getOwner(); return rc != null ? rc.getProject() : null; } protected Properties loadProperties(IConfiguration cfg, IBuildObject bo){ Map<String, Object> map = getData(cfg); return getPropsFromData(map, bo); } protected Properties getPropsFromData(Map<String, Object> data, IBuildObject bo){ synchronized (data) { Object oVal = data.get(bo.getId()); Properties props = null; if(oVal instanceof String){ props = stringToProps((String)oVal); data.put(bo.getId(), props); } else if (oVal instanceof Properties){ props = (Properties)oVal; } if(props == null){ props = new Properties(); data.put(bo.getId(), props); } return props; } } protected void storeData(IConfiguration cfg){ Map<String, Object> map = getLoaddedData(cfg); if(map != null) storeData(cfg, map); } protected Properties mapToProps(Map<String, Object> map){ Properties props = null; if(map != null){ synchronized(map){ if(map.size() > 0){ props = new Properties(); Set<Entry<String, Object>> entrySet = map.entrySet(); for (Entry<String, Object> entry : entrySet) { String key = entry.getKey(); String value = null; Object oVal = entry.getValue(); if(oVal instanceof Properties){ value = propsToString((Properties)oVal); } else if (oVal instanceof String){ value = (String)oVal; } if(key != null && value != null) props.setProperty(key, value); } } } } return props; } protected String propsToString(Properties props){ if(props == null || props.size() == 0) return null; ByteArrayOutputStream stream = new ByteArrayOutputStream(); try { props.store(stream, ""); //$NON-NLS-1$ } catch (IOException e1) { } byte[] bytes= stream.toByteArray(); String value = null; try { value= new String(bytes, "UTF-8"); //$NON-NLS-1$ } catch (UnsupportedEncodingException e) { value= new String(bytes); } return value; } protected Properties stringToProps(String str){ Properties props = null; if(str != null){ props = new Properties(); byte[] bytes; try { bytes = str.getBytes("UTF-8"); //$NON-NLS-1$ } catch (UnsupportedEncodingException e) { bytes = str.getBytes(); } ByteArrayInputStream stream = new ByteArrayInputStream(bytes); try { props.load(stream); } catch (IOException e) { props = null; } } return props; } protected void storeData(IConfiguration cfg, Map<String, Object> map){ String str = null; Properties props = mapToProps(map); str = propsToString(props); storeString(cfg, str); } protected void storeString(IConfiguration cfg, String str){ Preferences prefs = getNode(cfg.getManagedProject()); if(prefs != null){ if(str != null) prefs.put(cfg.getId(), str); else prefs.remove(cfg.getId()); try { prefs.flush(); } catch (BackingStoreException e) { } } } protected String loadString(IConfiguration cfg){ String str = null; Preferences prefs = getNode(cfg.getManagedProject()); if(prefs != null) str = prefs.get(cfg.getId(), null); return str; } protected Preferences getNode(IManagedProject mProject){ // return getProjNode(mProject); return getInstNode(mProject); } protected Preferences getProjNode(IManagedProject mProject){ IProject project = mProject.getOwner().getProject(); if(project == null || !project.exists() || !project.isOpen()) return null; Preferences prefs = new ProjectScope(project).getNode(ManagedBuilderCorePlugin.getUniqueIdentifier()); if(prefs != null) return prefs.node(NODE_NAME); return null; } protected Preferences getInstNode(IManagedProject mProject){ Preferences prefs = new InstanceScope().getNode(ManagedBuilderCorePlugin.getUniqueIdentifier()); if(prefs != null){ prefs = prefs.node(NODE_NAME); if(prefs != null) prefs = prefs.node(mProject.getId()); } return prefs; } protected Map<String, Object> getData(IConfiguration cfg){ Map<String, Object> map = getLoaddedData(cfg); if(map == null){ map = loadData(cfg); setLoaddedData(cfg, map); } return map; } protected Map<String, Object> loadData(IConfiguration cfg){ Map<String, Object> map = null; String str = loadString(cfg); Properties props = stringToProps(str); map = propsToMap(props); if(map == null) map = new HashMap<String, Object>(); return map; } protected Map<String, Object> propsToMap(Properties props){ if(props != null) { @SuppressWarnings({ "rawtypes", "unchecked" }) HashMap<String, Object> map = new HashMap(props); return map; } return null; } private static IConfiguration getConfigurationFromId(IProject project, String id){ if(project == null || id == null) return null; IManagedBuildInfo bInfo = ManagedBuildManager.getBuildInfo(project, false); IConfiguration cfg = null; if(bInfo != null){ IManagedProject mProj = bInfo.getManagedProject(); if(mProj != null){ cfg = mProj.getConfiguration(id); } } return cfg; } protected void setLoaddedData(IConfiguration cfg, Map<String, Object> data){ if(cfg.getOwner() == null) return; LoaddedInfo info = getLoaddedInfo(); if(info != null){ if(info.cfgMatch(cfg)){ info = new LoaddedInfo(info.getProject(), info.getConfigurationId(), data); setLoaddedInfo(info); return; } IConfiguration oldCfg = info.getConfiguration(); if(oldCfg != null){ storeData(oldCfg, info.getProperties()); } } IProject proj = cfg.getOwner().getProject(); info = new LoaddedInfo(proj, cfg.getId(), data); setLoaddedInfo(info); } public void setProperty(IConfiguration cfg, String key, String value){ setProperty(cfg, cfg, key, value); } public void setProperty(IResourceInfo rcInfo, String key, String value){ setProperty(rcInfo.getParent(), rcInfo, key, value); } public void setProperty(IToolChain tc, String key, String value){ setProperty(tc.getParent(), tc, key, value); } public void setProperty(ITool tool, String key, String value){ Configuration cfg = (Configuration)getConfiguration(tool); if(cfg.isPreference()) return; setProperty(cfg, tool, key, value); } public void setProperty(IBuilder builder, String key, String value){ setProperty(getConfiguration(builder), builder, key, value); } public String getProperty(IConfiguration cfg, String key){ return getProperty(cfg, cfg, key); } public String getProperty(IResourceInfo rcInfo, String key){ return getProperty(rcInfo.getParent(), rcInfo, key); } public String getProperty(IToolChain tc, String key){ return getProperty(tc.getParent(), tc, key); } public String getProperty(ITool tool, String key){ return getProperty(getConfiguration(tool), tool, key); } public String getProperty(IBuilder builder, String key){ return getProperty(getConfiguration(builder), builder, key); } public void clearProperties(IManagedProject mProject){ if(mProject == null) return; IConfiguration cfgs[] = mProject.getConfigurations(); for(int i = 0; i < cfgs.length; i++) clearLoaddedData(cfgs[i]); Preferences prefs = getNode(mProject); if(prefs != null){ try { Preferences parent = prefs.parent(); prefs.removeNode(); if(parent != null) parent.flush(); } catch (BackingStoreException e) { } } } public void clearProperties(IConfiguration cfg){ if(cfg.getOwner() == null) return; clearLoaddedData(cfg); storeData(cfg, null); } private IConfiguration getConfiguration(IBuilder builder){ IToolChain tc = builder.getParent(); if(tc != null) return tc.getParent(); return null; } private IConfiguration getConfiguration(ITool tool){ IBuildObject p = tool.getParent(); IConfiguration cfg = null; if(p instanceof IToolChain){ cfg = ((IToolChain)p).getParent(); } else if(p instanceof IResourceConfiguration){ cfg = ((IResourceConfiguration)p).getParent(); } return cfg; } public void serialize(IConfiguration cfg){ if(cfg.isTemporary() || cfg.getOwner() == null) return; storeData(cfg); } public void serialize(){ LoaddedInfo info = getLoaddedInfo(); IConfiguration cfg = info.getConfiguration(); if(cfg != null){ serialize(cfg); clearLoaddedData(cfg); } // IProject projects[] = ResourcesPlugin.getWorkspace().getRoot().getProjects(); // for(int i = 0; i < projects.length; i++){ // IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(projects[i], false); // if(info != null && info.isValid() && info.getManagedProject() != null){ // IConfiguration cfgs[] = info.getManagedProject().getConfigurations(); // for(int j = 0; j < cfgs.length; j++){ // serialize(cfgs[j]); // } // } // } } }