1 /*******************************************************************************
2 * Copyright (C) 2018, Luís Copetti <lhcopetti@gmail.com>
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License 2.0
6 * which accompanies this distribution, and is available at
7 * https://www.eclipse.org/legal/epl-2.0/
9 * SPDX-License-Identifier: EPL-2.0
10 *******************************************************************************/
11 package org
.eclipse
.egit
.ui
.internal
.branch
;
13 import java
.io
.IOException
;
14 import java
.io
.StringReader
;
15 import java
.io
.StringWriter
;
16 import java
.util
.Collections
;
17 import java
.util
.List
;
18 import java
.util
.stream
.Collectors
;
19 import java
.util
.stream
.Stream
;
21 import org
.eclipse
.egit
.ui
.Activator
;
22 import org
.eclipse
.jface
.preference
.IPreferenceStore
;
23 import org
.eclipse
.jgit
.lib
.Repository
;
24 import org
.eclipse
.jgit
.util
.StringUtils
;
25 import org
.eclipse
.ui
.IMemento
;
26 import org
.eclipse
.ui
.WorkbenchException
;
27 import org
.eclipse
.ui
.XMLMemento
;
30 * A helper class to simplify storing the association between project paths and
31 * (repository + branch). This API prevents the user
32 * {@link BranchProjectTracker} from knowing where these associations are being
33 * saved. For this particular case at a {@link IPreferenceStore} using
36 * The usual location for the file is at:
37 * .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.egit.ui.prefs
40 * An example entry would be: {@code
41 * //BranchProjectTracker__/absolute/path/to/git/repository/.git_BranchName=<?xml
43 * encoding\="UTF-8"?>\n<projects>\n<project>/</project>\n</projects> }
46 class ProjectTrackerPreferenceHelper
{
48 private static final String PREFIX
= "BranchProjectTracker_"; //$NON-NLS-1$
50 private static final String KEY_PROJECTS
= "projects"; //$NON-NLS-1$
52 private static final String KEY_PROJECT
= "project"; //$NON-NLS-1$
59 static void saveToPreferences(Repository repo
, String branch
,
60 List
<String
> projects
) {
61 XMLMemento preferencesMemento
= createXMLMemento(projects
);
62 String preferenceKey
= getPreferenceKey(repo
, branch
);
63 saveToPreferenceStore(preferenceKey
, preferencesMemento
);
66 private static XMLMemento
createXMLMemento(List
<String
> projectPaths
) {
67 XMLMemento memento
= XMLMemento
.createWriteRoot(KEY_PROJECTS
);
68 projectPaths
.forEach(path
-> {
69 IMemento child
= memento
.createChild(KEY_PROJECT
);
70 child
.putTextData(path
);
76 * Get preference key for branch. This will be unique to the repository and
83 static String
getPreferenceKey(Repository repo
,
84 final String branch
) {
85 return PREFIX
+ '_' + repo
.getDirectory().getAbsolutePath() + '_'
89 private static void saveToPreferenceStore(String key
, XMLMemento content
) {
90 IPreferenceStore store
= Activator
.getDefault().getPreferenceStore();
91 StringWriter writer
= new StringWriter();
94 store
.setValue(key
, writer
.toString());
95 } catch (IOException e
) {
96 Activator
.logError("Error writing branch-project associations", e
); //$NON-NLS-1$
101 * Load the project paths associated with the currently checked out branch.
102 * These paths will be relative to the supplied repository.
106 * @return non-null but possibly empty array of projects
108 static List
<String
> restoreFromPreferences(Repository repo
,
110 String key
= getPreferenceKey(repo
, branch
);
111 String value
= Activator
.getDefault().getPreferenceStore()
114 if (value
.isEmpty()) {
115 return Collections
.emptyList();
119 memento
= XMLMemento
.createReadRoot(new StringReader(value
));
120 } catch (WorkbenchException e
) {
121 Activator
.logError("Error reading branch-project associations", e
); //$NON-NLS-1$
122 return Collections
.emptyList();
124 IMemento
[] children
= memento
.getChildren(KEY_PROJECT
);
125 if (children
.length
== 0) {
126 return Collections
.emptyList();
128 List
<String
> projectPaths
= Stream
.of(children
)
129 .map(IMemento
::getTextData
)
130 .filter(x
-> !StringUtils
.isEmptyOrNull(x
))
131 .collect(Collectors
.toList());