Fix build
[egit.git] / org.eclipse.egit.ui / src / org / eclipse / egit / ui / internal / repository / RepositoryPropertySource.java
bloba66fa0d3186ca77c4b87f45dd95f79326d468d8a
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.window.Window;
27 import org.eclipse.jgit.errors.ConfigInvalidException;
28 import org.eclipse.jgit.lib.Config;
29 import org.eclipse.jgit.lib.FileBasedConfig;
30 import org.eclipse.jgit.lib.Repository;
31 import org.eclipse.jgit.lib.RepositoryConfig;
32 import org.eclipse.jgit.util.FS;
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(FS.DETECTED);
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 showExceptionMessage(e);
96 } catch (ConfigInvalidException e) {
97 showExceptionMessage(e);
101 private void makeActions() {
103 configureKeyAction = new Action(
104 UIText.RepositoryPropertySource_ConfigureKeysAction) {
106 @Override
107 public String getId() {
108 return "ConfigKeyActionId"; //$NON-NLS-1$
111 @Override
112 public void run() {
113 ConfigureKeysDialog dlg = new ConfigureKeysDialog(myPage
114 .getSite().getShell(), getConfiguredKeys());
115 if (dlg.open() == Window.OK)
116 try {
117 setConfiguredKeys(dlg.getActiveKeys());
118 myPage.refresh();
119 } catch (IOException e) {
120 showExceptionMessage(e);
127 modeToggleAction = new Action(
128 UIText.RepositoryPropertySource_EffectiveConfigurationAction) {
129 // TODO icon
130 @Override
131 public String getId() {
132 return "ViewModeToggle"; //$NON-NLS-1$
135 @Override
136 public void run() {
137 myPage.refresh();
140 @Override
141 public int getStyle() {
142 return IAction.AS_CHECK_BOX;
147 restoreKeyAction = new Action(
148 UIText.RepositoryPropertySource_RestoreStandardAction) {
150 @Override
151 public String getId() {
152 return "RestoreKeys"; //$NON-NLS-1$
155 @Override
156 public void run() {
157 try {
158 setConfiguredKeys(new ArrayList<String>());
159 myPage.refresh();
160 } catch (IOException e) {
161 showExceptionMessage(e);
168 private void addActions() {
170 boolean refreshToolbar = false;
171 IActionBars bars = myPage.getSite().getActionBars();
173 if (bars.getToolBarManager().find(modeToggleAction.getId()) == null) {
174 bars.getToolBarManager().add(modeToggleAction);
175 refreshToolbar = true;
178 if (bars.getMenuManager().find(configureKeyAction.getId()) == null)
179 bars.getMenuManager().add(configureKeyAction);
181 if (bars.getMenuManager().find(restoreKeyAction.getId()) == null)
182 bars.getMenuManager().add(restoreKeyAction);
184 if (refreshToolbar)
185 bars.getToolBarManager().update(false);
188 private List<String> getConfiguredKeys() {
190 List<String> result = new ArrayList<String>();
191 ScopedPreferenceStore store = new ScopedPreferenceStore(
192 new InstanceScope(), Activator.getPluginId());
193 String keys = store.getString(PREFERENCE_KEYS);
194 if (keys.length() > 0) {
195 StringTokenizer tok = new StringTokenizer(keys, " "); //$NON-NLS-1$
196 while (tok.hasMoreTokens()) {
197 result.add(tok.nextToken());
199 } else {
200 result.addAll(ConfigureKeysDialog.standardKeys);
202 return result;
205 private void setConfiguredKeys(List<String> keys) throws IOException {
207 StringBuilder sb = new StringBuilder();
208 for (String key : keys) {
209 sb.append(key);
210 sb.append(" "); //$NON-NLS-1$
212 ScopedPreferenceStore store = new ScopedPreferenceStore(
213 new InstanceScope(), Activator.getPluginId());
214 store.putValue(PREFERENCE_KEYS, sb.toString());
215 store.save();
219 private Object getValueFromConfig(Config config, String keyString) {
221 StringTokenizer tok = new StringTokenizer(keyString, "."); //$NON-NLS-1$
223 String section;
224 String subsection;
225 String name;
227 String[] valueList = null;
228 if (tok.countTokens() == 2) {
229 section = tok.nextToken();
230 subsection = null;
231 name = tok.nextToken();
232 } else if (tok.countTokens() == 3) {
233 section = tok.nextToken();
234 subsection = tok.nextToken();
235 name = tok.nextToken();
236 } else {
237 // TODO exception?
238 return null;
241 valueList = config.getStringList(section, subsection, name);
243 if (valueList == null || valueList.length == 0)
244 return null;
246 if (valueList.length == 1) {
247 return valueList[0];
250 StringBuilder sb = new StringBuilder();
251 for (String value: valueList){
252 sb.append('[');
253 sb.append(value);
254 sb.append(']');
257 return sb.toString();
261 public Object getEditableValue() {
262 return null;
265 public IPropertyDescriptor[] getPropertyDescriptors() {
267 // initFromConfig();
269 try {
270 userHomeConfig.load();
271 repositoryConfig.load();
272 effectiveConfig.load();
273 } catch (IOException e) {
274 showExceptionMessage(e);
275 } catch (ConfigInvalidException e) {
276 showExceptionMessage(e);
279 List<IPropertyDescriptor> resultList = new ArrayList<IPropertyDescriptor>();
281 List<String> configuredKeys = getConfiguredKeys();
283 boolean effectiveMode = false;
285 ActionContributionItem item = (ActionContributionItem) myPage.getSite()
286 .getActionBars().getToolBarManager().find(
287 modeToggleAction.getId());
288 if (item != null) {
289 effectiveMode = ((Action) item.getAction()).isChecked();
292 if (effectiveMode) {
293 for (String key : configuredKeys) {
295 for (String sub : getSubSections(effectiveConfig, key)) {
296 PropertyDescriptor desc = new PropertyDescriptor(
297 EFFECTIVE_ID_PREFIX + sub, sub);
299 desc
300 .setCategory(UIText.RepositoryPropertySource_EffectiveConfigurationCategory);
301 resultList.add(desc);
305 } else {
307 String categoryString = UIText.RepositoryPropertySource_GlobalConfigurationCategory
308 + userHomeConfig.getFile().getAbsolutePath();
309 for (String key : configuredKeys) {
311 // no remote configuration globally....
312 if (key.startsWith(RepositoriesView.REMOTE + ".")) //$NON-NLS-1$
313 continue;
315 for (String sub : getSubSections(effectiveConfig, key)) {
316 TextPropertyDescriptor desc = new TextPropertyDescriptor(
317 USER_ID_PREFIX + sub, sub);
318 desc.setCategory(categoryString);
319 resultList.add(desc);
322 categoryString = UIText.RepositoryPropertySource_RepositoryConfigurationCategory
323 + repositoryConfig.getFile().getAbsolutePath();
325 boolean editable = true;
327 for (String key : configuredKeys) {
329 // remote stuff is not configurable
330 editable = !key.startsWith("remote"); //$NON-NLS-1$
332 for (String sub : getSubSections(effectiveConfig, key)) {
333 PropertyDescriptor desc;
334 if (editable)
335 desc = new TextPropertyDescriptor(REPO_ID_PREFIX + sub,
336 sub);
337 else
338 desc = new PropertyDescriptor(REPO_ID_PREFIX + sub, sub);
339 desc.setCategory(categoryString);
340 resultList.add(desc);
345 return resultList.toArray(new IPropertyDescriptor[0]);
348 private List<String> getSubSections(Config configuration, String key) {
350 List<String> result = new ArrayList<String>();
352 if (key.indexOf(".?.") < 0) { //$NON-NLS-1$
353 result.add(key);
354 return result;
357 StringTokenizer stok = new StringTokenizer(key, "."); //$NON-NLS-1$
358 if (stok.countTokens() == 3) {
359 String section = stok.nextToken();
360 String subsection = stok.nextToken();
361 String name = stok.nextToken();
362 if (subsection.equals("?")) { //$NON-NLS-1$
363 Set<String> subs = configuration.getSubsections(section);
364 for (String sub : subs)
365 result.add(section + "." + sub + "." + name); //$NON-NLS-1$ //$NON-NLS-2$
366 return result;
367 } else {
368 result.add(key);
371 return result;
374 public Object getPropertyValue(Object id) {
375 String actId = ((String) id);
376 Object value = null;
377 if (actId.startsWith(USER_ID_PREFIX)) {
378 value = getValueFromConfig(userHomeConfig, actId.substring(4));
379 } else if (actId.startsWith(REPO_ID_PREFIX)) {
380 value = getValueFromConfig(repositoryConfig, actId.substring(4));
381 } else if (actId.startsWith(EFFECTIVE_ID_PREFIX)) {
382 value = getValueFromConfig(effectiveConfig, actId.substring(4));
384 if (value == null)
385 // the text editor needs this to work
386 return ""; //$NON-NLS-1$
388 return value;
391 public boolean isPropertySet(Object id) {
392 String actId = ((String) id);
393 Object value = null;
394 if (actId.startsWith(USER_ID_PREFIX)) {
395 value = getValueFromConfig(userHomeConfig, actId.substring(4));
396 } else if (actId.startsWith(REPO_ID_PREFIX)) {
397 value = getValueFromConfig(repositoryConfig, actId.substring(4));
398 } else if (actId.startsWith(EFFECTIVE_ID_PREFIX)) {
399 value = getValueFromConfig(effectiveConfig, actId.substring(4));
401 return value != null;
404 public void resetPropertyValue(Object id) {
405 setPropertyValue(id, null);
408 public void setPropertyValue(Object id, Object value) {
410 String actId = (String) id;
411 try {
412 if (actId.startsWith(USER_ID_PREFIX)) {
413 setConfigValue(userHomeConfig, actId.substring(4),
414 (String) value);
416 if (actId.startsWith(REPO_ID_PREFIX)) {
417 setConfigValue(repositoryConfig, actId.substring(4),
418 (String) value);
420 } catch (IOException e) {
421 showExceptionMessage(e);
426 public boolean isPropertyResettable(Object id) {
427 return isPropertySet(id);
430 private void setConfigValue(FileBasedConfig configuration, String key,
431 String value) throws IOException {
432 // we un-set empty strings, as the config API does not allow to
433 // distinguish this case
434 // (null is returned, even if the value is set to "", but in the
435 // effective configuration
436 // this results in shadowing of the base configured values
437 StringTokenizer tok = new StringTokenizer(key, "."); //$NON-NLS-1$
438 if (tok.countTokens() == 2) {
439 if (value == null || value.length() == 0) {
440 configuration.unset(tok.nextToken(), null, tok.nextToken());
441 } else {
442 configuration.setString(tok.nextToken(), null, tok.nextToken(),
443 value);
446 if (tok.countTokens() == 3) {
447 if (value == null || value.length() == 0) {
448 configuration.unset(tok.nextToken(), tok.nextToken(), tok
449 .nextToken());
450 } else {
451 configuration.setString(tok.nextToken(), tok.nextToken(), tok
452 .nextToken(), value);
456 configuration.save();
459 private void showExceptionMessage(Exception e) {
460 org.eclipse.egit.ui.Activator.handleError(UIText.RepositoryPropertySource_ErrorHeader, e, true);