Add Configuration to Repositories View
[egit/spearce.git] / org.eclipse.egit.ui / src / org / eclipse / egit / ui / internal / repository / RepositoryPropertySource.java
blobf2360428a07a5dd919e3d05b1ef5aa4772a6af08
1 /*******************************************************************************
2 * Copyright (c) 2010 SAP AG.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
8 * Contributors:
9 * Mathias Kinzler (SAP AG) - initial implementation
10 *******************************************************************************/
11 package org.eclipse.egit.ui.internal.repository;
13 import java.io.File;
14 import java.io.IOException;
15 import java.util.ArrayList;
16 import java.util.List;
17 import java.util.Set;
18 import java.util.StringTokenizer;
20 import org.eclipse.core.runtime.preferences.InstanceScope;
21 import org.eclipse.egit.core.Activator;
22 import org.eclipse.egit.ui.UIText;
23 import org.eclipse.jface.action.Action;
24 import org.eclipse.jface.action.ActionContributionItem;
25 import org.eclipse.jface.action.IAction;
26 import org.eclipse.jface.dialogs.MessageDialog;
27 import org.eclipse.jface.window.Window;
28 import org.eclipse.jgit.errors.ConfigInvalidException;
29 import org.eclipse.jgit.lib.Config;
30 import org.eclipse.jgit.lib.FileBasedConfig;
31 import org.eclipse.jgit.lib.Repository;
32 import org.eclipse.jgit.lib.RepositoryConfig;
33 import org.eclipse.jgit.util.SystemReader;
34 import org.eclipse.ui.IActionBars;
35 import org.eclipse.ui.preferences.ScopedPreferenceStore;
36 import org.eclipse.ui.views.properties.IPropertyDescriptor;
37 import org.eclipse.ui.views.properties.IPropertySource;
38 import org.eclipse.ui.views.properties.IPropertySource2;
39 import org.eclipse.ui.views.properties.PropertyDescriptor;
40 import org.eclipse.ui.views.properties.PropertySheetPage;
41 import org.eclipse.ui.views.properties.TextPropertyDescriptor;
43 /**
44 * Properties for repository configuration
47 public class RepositoryPropertySource implements IPropertySource,
48 IPropertySource2 {
50 private static final String USER_ID_PREFIX = "user"; //$NON-NLS-1$
52 private static final String REPO_ID_PREFIX = "repo"; //$NON-NLS-1$
54 private static final String EFFECTIVE_ID_PREFIX = "effe"; //$NON-NLS-1$
56 private static final String PREFERENCE_KEYS = "RepositoryPropertySource.ConfiguredKeys"; //$NON-NLS-1$
58 private Action configureKeyAction;
60 private Action modeToggleAction;
62 private Action restoreKeyAction;
64 private final PropertySheetPage myPage;
66 private final FileBasedConfig userHomeConfig;
68 private final FileBasedConfig repositoryConfig;
70 private final RepositoryConfig effectiveConfig;
72 /**
73 * @param rep
74 * the repository
75 * @param page
77 public RepositoryPropertySource(Repository rep, PropertySheetPage page) {
79 myPage = page;
81 makeActions();
82 addActions();
84 effectiveConfig = rep.getConfig();
85 userHomeConfig = SystemReader.getInstance().openUserConfig();
86 // TODO constant?
87 File configFile = new File(rep.getDirectory(), "config"); //$NON-NLS-1$
88 repositoryConfig = new FileBasedConfig(configFile);
90 try {
91 effectiveConfig.load();
92 userHomeConfig.load();
93 repositoryConfig.load();
94 } catch (IOException e) {
95 // TODO refactor to a method and react on exceptions
96 e.printStackTrace();
97 } catch (ConfigInvalidException e) {
98 // TODO refactor to a method and react on exceptions
99 e.printStackTrace();
104 private void makeActions() {
106 configureKeyAction = new Action(
107 UIText.RepositoryPropertySource_ConfigureKeysAction) {
109 @Override
110 public String getId() {
111 return "ConfigKeyActionId"; //$NON-NLS-1$
114 @Override
115 public void run() {
116 ConfigureKeysDialog dlg = new ConfigureKeysDialog(myPage
117 .getSite().getShell(), getConfiguredKeys());
118 if (dlg.open() == Window.OK)
119 try {
120 setConfiguredKeys(dlg.getActiveKeys());
121 myPage.refresh();
122 } catch (IOException e) {
123 showExceptionMessage(e);
130 modeToggleAction = new Action(
131 UIText.RepositoryPropertySource_EffectiveConfigurationAction) {
132 // TODO icon
133 @Override
134 public String getId() {
135 return "ViewModeToggle"; //$NON-NLS-1$
138 @Override
139 public void run() {
140 myPage.refresh();
143 @Override
144 public int getStyle() {
145 return IAction.AS_CHECK_BOX;
150 restoreKeyAction = new Action(
151 UIText.RepositoryPropertySource_RestoreStandardAction) {
153 @Override
154 public String getId() {
155 return "RestoreKeys"; //$NON-NLS-1$
158 @Override
159 public void run() {
160 try {
161 setConfiguredKeys(new ArrayList<String>());
162 myPage.refresh();
163 } catch (IOException e) {
164 showExceptionMessage(e);
171 private void addActions() {
173 boolean refreshToolbar = false;
174 IActionBars bars = myPage.getSite().getActionBars();
176 if (bars.getToolBarManager().find(modeToggleAction.getId()) == null) {
177 bars.getToolBarManager().add(modeToggleAction);
178 refreshToolbar = true;
181 if (bars.getMenuManager().find(configureKeyAction.getId()) == null)
182 bars.getMenuManager().add(configureKeyAction);
184 if (bars.getMenuManager().find(restoreKeyAction.getId()) == null)
185 bars.getMenuManager().add(restoreKeyAction);
187 if (refreshToolbar)
188 bars.getToolBarManager().update(false);
191 private List<String> getConfiguredKeys() {
193 List<String> result = new ArrayList<String>();
194 ScopedPreferenceStore store = new ScopedPreferenceStore(
195 new InstanceScope(), Activator.getPluginId());
196 String keys = store.getString(PREFERENCE_KEYS);
197 if (keys.length() > 0) {
198 StringTokenizer tok = new StringTokenizer(keys, " "); //$NON-NLS-1$
199 while (tok.hasMoreTokens()) {
200 result.add(tok.nextToken());
202 } else {
203 result.addAll(ConfigureKeysDialog.standardKeys);
205 return result;
208 private void setConfiguredKeys(List<String> keys) throws IOException {
210 StringBuilder sb = new StringBuilder();
211 for (String key : keys) {
212 sb.append(key);
213 sb.append(" "); //$NON-NLS-1$
215 ScopedPreferenceStore store = new ScopedPreferenceStore(
216 new InstanceScope(), Activator.getPluginId());
217 store.putValue(PREFERENCE_KEYS, sb.toString());
218 store.save();
222 private Object getValueFromConfig(Config config, String keyString) {
224 StringTokenizer tok = new StringTokenizer(keyString, "."); //$NON-NLS-1$
226 String section;
227 String subsection;
228 String name;
230 String[] valueList = null;
231 String value = null;
232 if (tok.countTokens() == 2) {
233 section = tok.nextToken();
234 subsection = null;
235 name = tok.nextToken();
236 } else if (tok.countTokens() == 3) {
237 section = tok.nextToken();
238 subsection = tok.nextToken();
239 name = tok.nextToken();
240 } else {
241 // TODO exception?
242 return null;
245 value = config.getString(section, subsection, name);
247 if (value != null)
248 return value;
250 valueList = config.getStringList(section, subsection, name);
252 if (valueList == null || valueList.length == 0)
253 return null;
255 if (valueList.length == 1) {
256 return valueList[0];
259 return valueList;
263 public Object getEditableValue() {
264 return null;
267 public IPropertyDescriptor[] getPropertyDescriptors() {
269 // initFromConfig();
271 try {
272 userHomeConfig.load();
273 repositoryConfig.load();
274 effectiveConfig.load();
275 } catch (IOException e) {
276 showExceptionMessage(e);
277 } catch (ConfigInvalidException e) {
278 showExceptionMessage(e);
281 List<IPropertyDescriptor> resultList = new ArrayList<IPropertyDescriptor>();
283 List<String> configuredKeys = getConfiguredKeys();
285 boolean effectiveMode = false;
287 ActionContributionItem item = (ActionContributionItem) myPage.getSite()
288 .getActionBars().getToolBarManager().find(
289 modeToggleAction.getId());
290 if (item != null) {
291 effectiveMode = ((Action) item.getAction()).isChecked();
294 if (effectiveMode) {
295 for (String key : configuredKeys) {
297 for (String sub : getSubSections(effectiveConfig, key)) {
298 PropertyDescriptor desc = new PropertyDescriptor(
299 EFFECTIVE_ID_PREFIX + sub, sub);
301 desc
302 .setCategory(UIText.RepositoryPropertySource_EffectiveConfigurationCategory);
303 resultList.add(desc);
307 } else {
309 String categoryString = UIText.RepositoryPropertySource_GlobalConfigurationCategory
310 + userHomeConfig.getFile().getAbsolutePath();
311 for (String key : configuredKeys) {
313 // no remote configuration globally....
314 if (key.startsWith(RepositoriesView.REMOTE + ".")) //$NON-NLS-1$
315 continue;
317 for (String sub : getSubSections(effectiveConfig, key)) {
318 TextPropertyDescriptor desc = new TextPropertyDescriptor(
319 USER_ID_PREFIX + sub, sub);
320 desc.setCategory(categoryString);
321 resultList.add(desc);
324 categoryString = UIText.RepositoryPropertySource_RepositoryConfigurationCategory
325 + repositoryConfig.getFile().getAbsolutePath();
326 for (String key : configuredKeys) {
328 for (String sub : getSubSections(effectiveConfig, key)) {
329 TextPropertyDescriptor desc = new TextPropertyDescriptor(
330 REPO_ID_PREFIX + sub, sub);
331 desc.setCategory(categoryString);
332 resultList.add(desc);
337 return resultList.toArray(new IPropertyDescriptor[0]);
340 private List<String> getSubSections(Config configuration, String key) {
342 List<String> result = new ArrayList<String>();
344 if (key.indexOf(".?.") < 0) { //$NON-NLS-1$
345 result.add(key);
346 return result;
349 StringTokenizer stok = new StringTokenizer(key, "."); //$NON-NLS-1$
350 if (stok.countTokens() == 3) {
351 String section = stok.nextToken();
352 String subsection = stok.nextToken();
353 String name = stok.nextToken();
354 if (subsection.equals("?")) { //$NON-NLS-1$
355 Set<String> subs = configuration.getSubsections(section);
356 for (String sub : subs)
357 result.add(section + "." + sub + "." + name); //$NON-NLS-1$ //$NON-NLS-2$
358 return result;
359 } else {
360 result.add(key);
363 return result;
366 public Object getPropertyValue(Object id) {
367 String actId = ((String) id);
368 Object value = null;
369 if (actId.startsWith(USER_ID_PREFIX)) {
370 value = getValueFromConfig(userHomeConfig, actId.substring(4));
371 } else if (actId.startsWith(REPO_ID_PREFIX)) {
372 value = getValueFromConfig(repositoryConfig, actId.substring(4));
373 } else if (actId.startsWith(EFFECTIVE_ID_PREFIX)) {
374 value = getValueFromConfig(effectiveConfig, actId.substring(4));
376 if (value == null)
377 // the text editor needs this to work
378 return ""; //$NON-NLS-1$
380 return value;
383 public boolean isPropertySet(Object id) {
384 String actId = ((String) id);
385 Object value = null;
386 if (actId.startsWith(USER_ID_PREFIX)) {
387 value = getValueFromConfig(userHomeConfig, actId.substring(4));
388 } else if (actId.startsWith(REPO_ID_PREFIX)) {
389 value = getValueFromConfig(repositoryConfig, actId.substring(4));
390 } else if (actId.startsWith(EFFECTIVE_ID_PREFIX)) {
391 value = getValueFromConfig(effectiveConfig, actId.substring(4));
393 return value != null;
396 public void resetPropertyValue(Object id) {
397 setPropertyValue(id, null);
400 public void setPropertyValue(Object id, Object value) {
402 String actId = (String) id;
403 try {
404 if (actId.startsWith(USER_ID_PREFIX)) {
405 setConfigValue(userHomeConfig, actId.substring(4),
406 (String) value);
408 if (actId.startsWith(REPO_ID_PREFIX)) {
409 setConfigValue(repositoryConfig, actId.substring(4),
410 (String) value);
412 } catch (IOException e) {
413 showExceptionMessage(e);
418 public boolean isPropertyResettable(Object id) {
419 return isPropertySet(id);
422 private void setConfigValue(FileBasedConfig configuration, String key,
423 String value) throws IOException {
424 // we un-set empty strings, as the config API does not allow to
425 // distinguish this case
426 // (null is returned, even if the value is set to "", but in the
427 // effective configuration
428 // this results in shadowing of the base configured values
429 StringTokenizer tok = new StringTokenizer(key, "."); //$NON-NLS-1$
430 if (tok.countTokens() == 2) {
431 if (value == null || value.length() == 0) {
432 configuration.unset(tok.nextToken(), null, tok.nextToken());
433 } else {
434 configuration.setString(tok.nextToken(), null, tok.nextToken(),
435 value);
438 if (tok.countTokens() == 3) {
439 if (value == null || value.length() == 0) {
440 configuration.unset(tok.nextToken(), tok.nextToken(), tok
441 .nextToken());
442 } else {
443 configuration.setString(tok.nextToken(), tok.nextToken(), tok
444 .nextToken(), value);
448 configuration.save();
451 private void showExceptionMessage(Exception e) {
452 MessageDialog.openError(myPage.getSite().getShell(),
453 UIText.RepositoryPropertySource_ErrorHeader, e.getMessage());