View Javadoc

1   /*
2    * This file is a part of CAST project.
3    * (c) Copyright 2007, AGH University of Science & Technology
4    * https://caribou.iisg.agh.edu.pl/trac/cast
5    *
6    * Licensed under the Eclipse Public License, Version 1.0 (the "License").
7    * You may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    * http://www.eclipse.org/legal/epl-v10.html
10   */
11  /*
12   * File: AbstractConfigurableView.java
13   * Created: 2007-00-00
14   * Author: awos, entrop
15   * $Id: UserPreferences.java 3266 2009-08-27 15:28:45Z tmilos $
16   */
17  
18  package pl.edu.agh.cast.project;
19  
20  import java.util.LinkedList;
21  import java.util.List;
22  
23  import org.apache.log4j.Logger;
24  import org.eclipse.core.resources.IProject;
25  import org.eclipse.core.runtime.preferences.IEclipsePreferences;
26  import org.eclipse.core.runtime.preferences.InstanceScope;
27  import org.osgi.service.prefs.BackingStoreException;
28  import org.osgi.service.prefs.Preferences;
29  
30  import pl.edu.agh.cast.Activator;
31  import pl.edu.agh.cast.CastApplication;
32  
33  /**
34   * Contains global user preferences.
35   *
36   * @author AGH CAST Team
37   */
38  public class UserPreferences {
39  
40  	/**
41  	 * Enumeration of user preferences.
42  	 *
43  	 * @author AGH CAST Team
44  	 */
45  	public static enum Pref {
46  
47  		/**
48  		 * User preference: <em>Show project startup dialog</em>.
49  		 */
50  		SHOW_PROJECT_STARTUP_DIALOG("showProjectStartupDialog"); //$NON-NLS-1$
51  
52  		private String value;
53  
54  		public String getValue() {
55  			return value;
56  		}
57  
58  		private Pref(String value) {
59  			this.value = value;
60  		}
61  
62  	}
63  
64  	private static final String KEY_CONFIGURATION_ID_NAME = "KEY_CONFIGURATION_ID"; //$NON-NLS-1$
65  
66  	private static final String ORG_ECLIPSE_UI_NODE_NAME = "org.eclipse.ui"; //$NON-NLS-1$
67  
68  	private static final String MRU_ORDER_NODE_NAME = "order"; //$NON-NLS-1$
69  
70  	private static final String MRU_PROJECT_NAME_PREFIX = "#"; //$NON-NLS-1$
71  
72  	private static final String MRU_NODE_NAME = "MRU"; //$NON-NLS-1$
73  
74  	private static final Logger LOG = Activator.getLogger();
75  
76  	private static UserPreferences instance;
77  
78  	/**
79  	 * Returns single, shared instance of {@link UserPreferences}.
80  	 *
81  	 * @return single, shared instance of {@link UserPreferences}
82  	 */
83  	public static UserPreferences getInstance() {
84  		if (instance == null) {
85  			instance = new UserPreferences();
86  		}
87  		return instance;
88  	}
89  
90  	/**
91  	 * Removes project from Most Recently Used (MRU) list.
92  	 *
93  	 * @param name
94  	 *            name of the project
95  	 */
96  	public void removeMRUProject(String name) {
97  		try {
98  			Preferences pluginNode = getPluginNode().node(MRU_NODE_NAME);
99  
100 			Preferences orderNode = pluginNode.node(MRU_ORDER_NODE_NAME);
101 			List<String> order = readNode(orderNode);
102 			order.remove(name);
103 			writeNode(orderNode, order);
104 
105 			Preferences projectNode = pluginNode.node(MRU_PROJECT_NAME_PREFIX + name);
106 			projectNode.removeNode();
107 
108 			pluginNode.flush();
109 		} catch (BackingStoreException e) {
110 			LOG.error("Failed to remove project from MRU list", e); //$NON-NLS-1$
111 		}
112 
113 	}
114 
115 	/**
116 	 * Returns a list of MRU projects.
117 	 *
118 	 * @return a list of MRU projects
119 	 */
120 	public List<MostRecentlyUsedProject> getMostRecentlyUsedProjects() {
121 		List<MostRecentlyUsedProject> projects = new LinkedList<MostRecentlyUsedProject>();
122 		Preferences mruNode = getPluginNode().node(MRU_NODE_NAME);
123 		List<String> order = readNode(mruNode.node(MRU_ORDER_NODE_NAME));
124 		for (String projName : order) {
125 			List<String> locations = readNode(mruNode.node(MRU_PROJECT_NAME_PREFIX + projName));
126 			projects.add(new MostRecentlyUsedProject(projName, locations));
127 		}
128 		return projects;
129 	}
130 
131 	/**
132 	 * Changes MRU project name. If project is bound to only one location then replaces old project with new one. If
133 	 * project is bound to more locations -> removes actual project location from 'old name project' bound, and adds new
134 	 * project name with actual location.
135 	 *
136 	 *
137 	 * @param project
138 	 *            Project with old name.
139 	 * @param newName
140 	 *            Future new name of project.
141 	 */
142 	public void changeMostRecentlyProjectName(IProject project, String newName) {
143 		String oldName = ProjectUtil.getInstance().getDisplayName(project);
144 		if (oldName.equals(newName)) {
145 			return;
146 		}
147 
148 		try {
149 			Preferences mruNode = getPluginNode().node(MRU_NODE_NAME);
150 			Preferences orderNode = mruNode.node(MRU_ORDER_NODE_NAME);
151 			List<String> order = readNode(orderNode);
152 
153 			Preferences oldProjectNode = mruNode.node(MRU_PROJECT_NAME_PREFIX + oldName);
154 			List<String> projDirs = readNode(oldProjectNode);
155 
156 			String projectDir = project.getLocation().toPortableString();
157 			if (projDirs.size() == 1) {
158 				// replace old name with new name in 'order' node
159 				setMostRecent(orderNode, oldName);
160 				order.set(0, newName);
161 				writeNode(orderNode, order);
162 
163 				// if old project registered in only one location then remove
164 				// old project node
165 				oldProjectNode.removeNode();
166 			} else {
167 				// if old project registered in many locations then remove
168 				// active location from old project
169 				setMostRecent(orderNode, newName);
170 				setMostRecent(oldProjectNode, projectDir);
171 				oldProjectNode = mruNode.node(MRU_PROJECT_NAME_PREFIX + oldName);
172 				projDirs.remove(0);
173 				writeNode(oldProjectNode, projDirs);
174 			}
175 
176 			Preferences newProjectNode = mruNode.node(MRU_PROJECT_NAME_PREFIX + newName);
177 
178 			// add project location to new project node
179 			setMostRecent(newProjectNode, projectDir);
180 
181 			mruNode.flush();
182 
183 		} catch (BackingStoreException ex) {
184 			LOG.error("Failed to change name for MRU project", ex); //$NON-NLS-1$
185 		}
186 	}
187 
188 	/**
189 	 * MRU projects are kept in the preferences in the following form
190 	 *
191 	 * <pre>
192 	 * MRU
193 	 * |_ order
194 	 *    |_ 0 = project_name0
195 	 *    |_ 1 = project_name1
196 	 *    ...
197 	 *    |_ n = project_namen
198 	 * |_ #project_name0
199 	 *    |_ 0 = most_recent_location
200 	 *    |_ 1 = older_location
201 	 *    ...
202 	 *    |_ n = oldest_location
203 	 * |_ #project_name1
204 	 *    ...
205 	 * ...
206 	 * </pre>
207 	 *
208 	 * @param p
209 	 *            project to set as most recently used
210 	 */
211 	public void registerMostRecentlyUsedProject(IProject p) {
212 		try {
213 			String projectName = ProjectUtil.getInstance().getDisplayName(p);
214 			String projectLoc = p.getLocation().toPortableString();
215 
216 			Preferences mruNode = getPluginNode().node(MRU_NODE_NAME);
217 			Preferences orderNode = mruNode.node(MRU_ORDER_NODE_NAME);
218 			Preferences projectNode = mruNode.node(MRU_PROJECT_NAME_PREFIX + projectName);
219 
220 			setMostRecent(orderNode, projectName);
221 			setMostRecent(projectNode, projectLoc);
222 
223 			mruNode.flush();
224 		} catch (BackingStoreException e) {
225 			LOG.error("Failed to save MRU project", e); //$NON-NLS-1$
226 		}
227 
228 	}
229 
230 	private void setMostRecent(Preferences node, String entry) throws BackingStoreException {
231 		List<String> entries = readNode(node);
232 		entries.remove(entry);
233 		entries.add(0, entry);
234 		writeNode(node, entries);
235 	}
236 
237 	private List<String> readNode(Preferences node) {
238 		List<String> entries = new LinkedList<String>();
239 		Integer i = 0;
240 		String entry;
241 		while ((entry = node.get(i.toString(), null)) != null) {
242 			entries.add(entry);
243 			i++;
244 		}
245 		return entries;
246 	}
247 
248 	private void writeNode(Preferences projectNode, List<String> locations) throws BackingStoreException {
249 		projectNode.clear();
250 		Integer i = 0;
251 		for (String loc : locations) {
252 			projectNode.put(i.toString(), loc);
253 			i++;
254 		}
255 	}
256 
257 	/**
258 	 * Sets the value of given preference.
259 	 *
260 	 * @param pref
261 	 *            preference
262 	 * @param val
263 	 *            the value
264 	 */
265 	public void setPreference(Pref pref, String val) {
266 		Preferences node = getPluginNode();
267 		node.put(pref.getValue(), val);
268 		try {
269 			node.flush();
270 		} catch (BackingStoreException e) {
271 			Activator.getLogger().error("Failed to save preference " + pref, e); //$NON-NLS-1$
272 		}
273 	}
274 
275 	/**
276 	 * Returns the value of given preference.
277 	 *
278 	 * @param pref
279 	 *            preference
280 	 * @return the value
281 	 */
282 	public String getPreference(Pref pref) {
283 		Preferences node = getPluginNode();
284 		return node.get(pref.getValue(), null);
285 	}
286 
287 	/**
288 	 * Initializes default preference values.
289 	 */
290 	public void initializeDefaults() {
291 		InstanceScope is = new InstanceScope();
292 		IEclipsePreferences uiNode = is.getNode(ORG_ECLIPSE_UI_NODE_NAME);
293 		if (uiNode.get(KEY_CONFIGURATION_ID_NAME, null) == null) {
294 			uiNode.put(KEY_CONFIGURATION_ID_NAME, CastApplication.KEY_SCHEME_ID);
295 		}
296 		try {
297 			uiNode.flush();
298 		} catch (BackingStoreException e) {
299 			Activator.getLogger().error("Failed to save default prefs", e); //$NON-NLS-1$
300 		}
301 	}
302 
303 	private static Preferences getPluginNode() {
304 		InstanceScope is = new InstanceScope();
305 		return is.getNode(Activator.PLUGIN_ID);
306 	}
307 
308 }