Skip to content

Commit 3ade724

Browse files
Copilotlaeubi
andcommitted
Add comprehensive documentation for Hierarchical Project Preferences
Co-authored-by: laeubi <[email protected]>
1 parent 192a97a commit 3ade724

File tree

1 file changed

+189
-0
lines changed

1 file changed

+189
-0
lines changed
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
# Hierarchical Project Preferences
2+
3+
## Overview
4+
5+
Hierarchical Project Preferences is a feature that allows nested projects to inherit preference values from their ancestor projects. This simplifies the management of preferences across multiple related projects.
6+
7+
## How It Works
8+
9+
### Project Nesting
10+
11+
A project A is considered nested within a project B if:
12+
```
13+
B.getLocation().isPrefixOf(A.getLocation())
14+
```
15+
16+
For example:
17+
```
18+
/workspace
19+
/projectB (at /path/to/projectB)
20+
/projectA (at /path/to/projectB/projectA)
21+
```
22+
23+
In this structure, projectA is nested within projectB.
24+
25+
### Preference Inheritance
26+
27+
When hierarchical project preferences are enabled:
28+
29+
1. Preferences are searched up the chain of nested projects
30+
2. Values from deeper nested projects override values from ancestor projects
31+
3. If a nested project doesn't have a preference file, it can still inherit from ancestors
32+
4. All preference files remain unchanged - inheritance is read-only
33+
34+
### Example
35+
36+
Consider this project structure:
37+
```
38+
/workspace
39+
/projectRoot (has key1=rootValue, key2=rootValue)
40+
/projectMid (has key2=midValue, key3=midValue)
41+
/projectLeaf (has key3=leafValue)
42+
```
43+
44+
When reading preferences from projectLeaf:
45+
- `key1` will be `rootValue` (inherited from projectRoot)
46+
- `key2` will be `midValue` (inherited from projectMid, which overrides projectRoot)
47+
- `key3` will be `leafValue` (from projectLeaf itself)
48+
49+
## Enabling/Disabling the Feature
50+
51+
The feature is controlled by the preference:
52+
```java
53+
ResourcesPlugin.PREF_ENABLE_HIERARCHICAL_PROJECT_PREFERENCES
54+
```
55+
56+
Default value: `true` (enabled)
57+
58+
To disable hierarchical preferences programmatically:
59+
```java
60+
Preferences node = Platform.getPreferencesService().getRootNode()
61+
.node(InstanceScope.SCOPE)
62+
.node(ResourcesPlugin.PI_RESOURCES);
63+
node.putBoolean(ResourcesPlugin.PREF_ENABLE_HIERARCHICAL_PROJECT_PREFERENCES, false);
64+
node.flush();
65+
```
66+
67+
## Use Cases
68+
69+
### 1. Shared Team Settings
70+
71+
Apply common settings to all projects in a workspace or directory:
72+
```
73+
/myWorkspace
74+
/teamSettings (contains shared team preferences)
75+
/project1 (inherits team settings)
76+
/project2 (inherits team settings)
77+
/project3 (can override specific settings while inheriting others)
78+
```
79+
80+
### 2. Modular Applications
81+
82+
In a modular application with multiple sub-projects:
83+
```
84+
/myApp
85+
/core (defines base preferences)
86+
/ui-module (inherits and may override)
87+
/api-module (inherits and may override)
88+
/impl-module (inherits and may override)
89+
```
90+
91+
### 3. Configuration Hierarchies
92+
93+
Set up configuration hierarchies for different environments:
94+
```
95+
/config
96+
/base (common settings)
97+
/development (dev-specific overrides)
98+
/dev-project1
99+
/dev-project2
100+
/production (prod-specific overrides)
101+
/prod-project1
102+
/prod-project2
103+
```
104+
105+
## Implementation Details
106+
107+
### ProjectNestingCache
108+
109+
The `ProjectNestingCache` class efficiently caches project nesting relationships:
110+
- Cache is computed lazily on first access
111+
- Cache is cleared when projects are deleted or moved
112+
- Projects without accessible locations are automatically filtered out
113+
114+
### Performance Considerations
115+
116+
- Preference loading is performed only once per preference node (cached in `loadedNodes`)
117+
- The nesting cache reduces the need to recompute project relationships
118+
- Cache is cleared conservatively to ensure correctness
119+
120+
### API Compatibility
121+
122+
This feature is fully backward compatible:
123+
- When disabled, behavior is identical to previous versions
124+
- No changes to existing preference file formats
125+
- Preference files are never modified by inheritance
126+
127+
## Testing
128+
129+
The implementation includes comprehensive tests covering:
130+
- Simple nesting (2 levels)
131+
- Multi-level nesting (3+ levels)
132+
- Nested projects without preference files
133+
- Inheritance through intermediate projects without preferences
134+
- File immutability (inheritance doesn't modify files)
135+
- Disabling the feature
136+
- Complex nesting scenarios with multiple preferences
137+
138+
Each test includes ASCII art diagrams to illustrate the project structure.
139+
140+
## API
141+
142+
### New Constants
143+
144+
#### `ResourcesPlugin.PREF_ENABLE_HIERARCHICAL_PROJECT_PREFERENCES`
145+
Preference key to enable/disable hierarchical project preferences.
146+
- Type: `String`
147+
- Value: `"enableHierarchicalProjectPreferences"`
148+
- Since: 3.20
149+
150+
#### `ResourcesPlugin.DEFAULT_PREF_ENABLE_HIERARCHICAL_PROJECT_PREFERENCES`
151+
Default value for hierarchical project preferences preference.
152+
- Type: `boolean`
153+
- Value: `true`
154+
- Since: 3.20
155+
156+
### New Classes
157+
158+
#### `ProjectNestingCache` (internal)
159+
Cache for project nesting relationships.
160+
- Package: `org.eclipse.core.internal.resources`
161+
- Since: 3.20
162+
163+
**Key Methods:**
164+
- `getAncestorProjects(IProject, Workspace)` - Returns list of ancestor projects
165+
- `clearCache()` - Clears the entire cache
166+
- `clearCache(IProject)` - Clears cache for specific project
167+
168+
## Migration Guide
169+
170+
No migration is required. The feature is enabled by default and works transparently with existing projects.
171+
172+
To disable the feature workspace-wide, add this to your workspace preferences:
173+
```
174+
org.eclipse.core.resources/enableHierarchicalProjectPreferences=false
175+
```
176+
177+
## Known Limitations
178+
179+
1. Only file system locations are considered for nesting - linked resources don't affect nesting relationships
180+
2. Projects must be open and accessible to participate in the hierarchy
181+
3. Circular nesting is not possible (by definition of `isPrefixOf`)
182+
183+
## Future Enhancements
184+
185+
Possible future improvements:
186+
- UI to visualize project nesting relationships
187+
- Preference to show inherited values differently in the preferences UI
188+
- Support for excluding specific qualifiers from inheritance
189+
- Performance optimizations for very large project hierarchies

0 commit comments

Comments
 (0)