Skip to content

Commit 606f9f2

Browse files
committed
Merge pull request #102 from scijava/create_pref_service
Migrates the static utility `Prefs` class to an extensible `PrefService`.
2 parents 5ab7872 + a0c6c95 commit 606f9f2

16 files changed

+1078
-155
lines changed

src/main/java/org/scijava/io/DefaultRecentFileService.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,10 @@
4848
import org.scijava.module.ModuleService;
4949
import org.scijava.plugin.Parameter;
5050
import org.scijava.plugin.Plugin;
51+
import org.scijava.prefs.PrefService;
5152
import org.scijava.service.AbstractService;
5253
import org.scijava.service.Service;
5354
import org.scijava.util.FileUtils;
54-
import org.scijava.util.Prefs;
5555

5656
// TODO - DefaultRecentFileService, DefaultWindowService, and DefaultLUTService
5757
// all build menus dynamically (see createInfo()). We may be able to abstract a
@@ -98,6 +98,9 @@ public final class DefaultRecentFileService extends AbstractService implements
9898
@Parameter
9999
private CommandService commandService;
100100

101+
@Parameter
102+
private PrefService prefService;
103+
101104
private List<String> recentFiles;
102105
private Map<String, ModuleInfo> recentModules;
103106

@@ -112,7 +115,7 @@ public void add(final String path) {
112115
recentFiles.add(path);
113116

114117
// persist the updated list
115-
Prefs.putList(recentFiles, RECENT_FILES_KEY);
118+
prefService.putList(recentFiles, RECENT_FILES_KEY);
116119

117120
if (present) {
118121
// path already present; update linked module info
@@ -136,7 +139,7 @@ public boolean remove(final String path) {
136139
final boolean success = recentFiles.remove(path);
137140

138141
// persist the updated list
139-
Prefs.putList(recentFiles, RECENT_FILES_KEY);
142+
prefService.putList(recentFiles, RECENT_FILES_KEY);
140143

141144
// remove linked module info
142145
final ModuleInfo info = recentModules.remove(path);
@@ -148,7 +151,7 @@ public boolean remove(final String path) {
148151
@Override
149152
public void clear() {
150153
recentFiles.clear();
151-
Prefs.clear(RECENT_FILES_KEY);
154+
prefService.clear(RECENT_FILES_KEY);
152155

153156
// unregister the modules with the module service
154157
moduleService.removeModules(recentModules.values());
@@ -165,7 +168,7 @@ public List<String> getRecentFiles() {
165168

166169
@Override
167170
public void initialize() {
168-
recentFiles = Prefs.getList(RECENT_FILES_KEY);
171+
recentFiles = prefService.getList(RECENT_FILES_KEY);
169172
recentModules = new HashMap<String, ModuleInfo>();
170173
for (final String path : recentFiles) {
171174
recentModules.put(path, createInfo(path));

src/main/java/org/scijava/module/AbstractModuleItem.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ public String getPersistKey() {
137137
* value for null.
138138
*/
139139
@Override
140+
@Deprecated
140141
public T loadValue() {
141142
// if there is nothing to load from persistence return nothing
142143
if (!isPersisted()) return null;
@@ -157,6 +158,7 @@ public T loadValue() {
157158
}
158159

159160
@Override
161+
@Deprecated
160162
public void saveValue(final T value) {
161163
if (!isPersisted()) return;
162164

src/main/java/org/scijava/module/DefaultModuleService.java

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import org.scijava.plugin.Parameter;
5555
import org.scijava.plugin.Plugin;
5656
import org.scijava.plugin.PluginService;
57+
import org.scijava.prefs.PrefService;
5758
import org.scijava.service.AbstractService;
5859
import org.scijava.service.Service;
5960
import org.scijava.thread.ThreadService;
@@ -87,6 +88,9 @@ public class DefaultModuleService extends AbstractService implements
8788
@Parameter
8889
private ThreadService threadService;
8990

91+
@Parameter
92+
private PrefService prefService;
93+
9094
/** Index of registered modules. */
9195
private ModuleIndex moduleIndex;
9296

@@ -255,6 +259,54 @@ public <T> ModuleItem<T> getSingleOutput(final Module module,
255259
return getSingleItem(module, type, module.getInfo().outputs());
256260
}
257261

262+
@Override
263+
public <T> void save(final ModuleItem<T> item, final T value) {
264+
if (!item.isPersisted()) return;
265+
266+
final String sValue = value == null ? "" : value.toString();
267+
268+
// do not persist if object cannot be converted back from a string
269+
if (!ConversionUtils.canConvert(sValue, item.getType())) return;
270+
271+
final String persistKey = item.getPersistKey();
272+
if (persistKey == null || persistKey.isEmpty()) {
273+
// Attempt to use prefService
274+
if (AbstractModuleItem.class.isAssignableFrom(item.getClass())) {
275+
final Class<?> prefClass = ((AbstractModuleItem<T>)item).getDelegateClass();
276+
final String prefKey = item.getName();
277+
prefService.put(prefClass, prefKey, sValue);
278+
}
279+
// Have to use ModuleItem#saveValue
280+
else item.saveValue(value);
281+
}
282+
else prefService.put(persistKey, sValue);
283+
}
284+
285+
@Override
286+
public <T> T load(final ModuleItem<T> item) {
287+
// if there is nothing to load from persistence return nothing
288+
if (!item.isPersisted()) return null;
289+
290+
final String sValue;
291+
final String persistKey = item.getPersistKey();
292+
if (persistKey == null || persistKey.isEmpty()) {
293+
// Attempt to use prefService
294+
if (AbstractModuleItem.class.isAssignableFrom(item.getClass())) {
295+
final Class<?> prefClass = ((AbstractModuleItem<T>)item).getDelegateClass();
296+
final String prefKey = item.getName();
297+
sValue = prefService.get(prefClass, prefKey);
298+
}
299+
// Have to use ModuleItem#loadValue
300+
else return item.loadValue();
301+
}
302+
else sValue = prefService.get(persistKey);
303+
304+
// if persisted value has never been set before return null
305+
if (sValue == null) return null;
306+
307+
return ConversionUtils.convert(sValue, item.getType());
308+
}
309+
258310
// -- Service methods --
259311

260312
@Override
@@ -383,5 +435,4 @@ private <T> ModuleItem<T> getSingleItem(final Module module,
383435
}
384436
return result;
385437
}
386-
387438
}

src/main/java/org/scijava/module/ModuleItem.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,21 @@ public interface ModuleItem<T> extends BasicDetails {
9393
* Note that this is different than obtaining a module instance's current
9494
* value for the input; see {@link #getValue(Module)} for that.
9595
* </p>
96+
*
97+
* @deprecated
98+
* @see ModuleService#load(ModuleItem)
9699
*/
100+
@Deprecated
97101
T loadValue();
98102

99103
/**
100104
* Saves the given value to persistent storage. This allows later restoration
101105
* of the value via {@link #loadValue()}, even from a different JVM.
106+
*
107+
* @deprecated
108+
* @see ModuleService#save(ModuleItem, Object)
102109
*/
110+
@Deprecated
103111
void saveValue(T value);
104112

105113
/** Gets the function that is called to initialize the item's value. */

src/main/java/org/scijava/module/ModuleService.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.scijava.module.process.ModulePreprocessor;
4343
import org.scijava.module.process.PostprocessorPlugin;
4444
import org.scijava.module.process.PreprocessorPlugin;
45+
import org.scijava.prefs.PrefService;
4546
import org.scijava.service.SciJavaService;
4647

4748
/**
@@ -273,4 +274,15 @@ <M extends Module> Future<M> run(M module,
273274
*/
274275
<T> ModuleItem<T> getSingleOutput(Module module, Class<T> type);
275276

277+
/**
278+
* Registers the given value for the given {@link ModuleItem} using the
279+
* {@link PrefService}.
280+
*/
281+
<T> void save(ModuleItem<T> item, T value);
282+
283+
/**
284+
* Returns the value, if any, stored in the {@link PrefService} for the given
285+
* {@link ModuleItem}.
286+
*/
287+
<T> T load(ModuleItem<T> item);
276288
}

src/main/java/org/scijava/module/process/LoadInputsPreprocessor.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333

3434
import org.scijava.module.Module;
3535
import org.scijava.module.ModuleItem;
36+
import org.scijava.module.ModuleService;
37+
import org.scijava.plugin.Parameter;
3638
import org.scijava.plugin.Plugin;
3739
import org.scijava.util.ConversionUtils;
3840
import org.scijava.widget.InputHarvester;
@@ -52,6 +54,9 @@
5254
priority = InputHarvester.PRIORITY + 1)
5355
public class LoadInputsPreprocessor extends AbstractPreprocessorPlugin {
5456

57+
@Parameter
58+
private ModuleService moduleService;
59+
5560
// -- ModuleProcessor methods --
5661

5762
@Override
@@ -69,9 +74,9 @@ private <T> void loadValue(final Module module, final ModuleItem<T> item) {
6974
// skip input that has already been resolved
7075
if (module.isResolved(item.getName())) return;
7176

77+
final T prefValue = moduleService.load(item);
7278
final Class<T> type = item.getType();
7379
final T defaultValue = item.getValue(module);
74-
final T prefValue = item.loadValue();
7580
final T value = getBestValue(prefValue, defaultValue, type);
7681
item.setValue(module, value);
7782
}

src/main/java/org/scijava/module/process/SaveInputsPreprocessor.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import org.scijava.Priority;
3535
import org.scijava.module.Module;
3636
import org.scijava.module.ModuleItem;
37+
import org.scijava.module.ModuleService;
38+
import org.scijava.plugin.Parameter;
3739
import org.scijava.plugin.Plugin;
3840

3941
/**
@@ -51,6 +53,9 @@
5153
priority = Priority.VERY_LOW_PRIORITY - 1)
5254
public class SaveInputsPreprocessor extends AbstractPreprocessorPlugin {
5355

56+
@Parameter
57+
private ModuleService moduleService;
58+
5459
// -- ModuleProcessor methods --
5560

5661
@Override
@@ -66,7 +71,7 @@ public void process(final Module module) {
6671
/** Saves the value of the given module item to persistent storage. */
6772
private <T> void saveValue(final Module module, final ModuleItem<T> item) {
6873
final T value = item.getValue(module);
69-
item.saveValue(value);
74+
moduleService.save(item, value);
7075
}
7176

7277
}

src/main/java/org/scijava/options/OptionsPlugin.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,11 @@
3434
import org.scijava.command.DynamicCommand;
3535
import org.scijava.event.EventService;
3636
import org.scijava.module.ModuleItem;
37+
import org.scijava.module.ModuleService;
3738
import org.scijava.options.event.OptionsEvent;
3839
import org.scijava.plugin.Parameter;
3940
import org.scijava.plugin.SingletonPlugin;
40-
import org.scijava.util.Prefs;
41+
import org.scijava.prefs.PrefService;
4142

4243
// TODO - outline for how to address issues with options (initializing, aggregating into 1 dialog)
4344

@@ -77,6 +78,12 @@ public class OptionsPlugin extends DynamicCommand implements SingletonPlugin {
7778
@Parameter
7879
protected EventService eventService;
7980

81+
@Parameter
82+
private PrefService prefService;
83+
84+
@Parameter
85+
private ModuleService moduleService;
86+
8087
// -- OptionsPlugin methods --
8188

8289
/** Loads option values from persistent storage. */
@@ -95,7 +102,7 @@ public void save() {
95102

96103
/** Clears option values from persistent storage. */
97104
public void reset() {
98-
Prefs.clear(getClass());
105+
prefService.clear(getClass());
99106
}
100107

101108
// -- Runnable methods --
@@ -116,13 +123,13 @@ public void run() {
116123
// -- Helper methods --
117124

118125
private <T> void loadInput(final ModuleItem<T> input) {
119-
final T value = input.loadValue();
126+
final T value = moduleService.load(input);
120127
if (value != null) input.setValue(this, value);
121128
}
122129

123130
private <T> void saveInput(final ModuleItem<T> input) {
124131
final T value = input.getValue(this);
125-
input.saveValue(value);
132+
moduleService.save(input, value);
126133
}
127134

128135
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* #%L
3+
* SciJava Common shared library for SciJava software.
4+
* %%
5+
* Copyright (C) 2009 - 2014 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.prefs;
33+
34+
import org.scijava.service.AbstractService;
35+
import org.scijava.util.Prefs;
36+
37+
/**
38+
* Abstract {@link PrefService} implementation. Calls
39+
* {@link Prefs#setDelegateService(PrefService, double)} on this {@code Service}
40+
* during initialization.
41+
*
42+
* @author Mark Hiner
43+
*/
44+
@SuppressWarnings({ "javadoc", "deprecation" })
45+
public abstract class AbstractPrefService extends AbstractService implements
46+
PrefService
47+
{
48+
49+
@Override
50+
public void initialize() {
51+
Prefs.setDelegateService(this, getPriority());
52+
}
53+
}

0 commit comments

Comments
 (0)