Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DefaultModuleService: change persisting of items #236

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions src/main/java/org/scijava/ItemPersistence.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* #%L
* SciJava Common shared library for SciJava software.
* %%
* Copyright (C) 2009 - 2016 Board of Regents of the University of
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
* Institute of Molecular Cell Biology and Genetics.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* #L%
*/

package org.scijava;

import org.scijava.plugin.Parameter;

/**
* Defines the persistence setting of a parameter.
*
* @author Stefan Helfrich
*/
public enum ItemPersistence {

/**
* Item is persisted in any case.
*/
YES,

/**
* Item is never persisted.
*/
NO,

/**
* Item is persisted unless an additional {@link Parameter#initializer()
* initializer()} method is defined or the value to persist is the defined
* default value.
*/
DEFAULT

}
3 changes: 2 additions & 1 deletion src/main/java/org/scijava/command/CommandModuleItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import java.util.List;

import org.scijava.ItemIO;
import org.scijava.ItemPersistence;
import org.scijava.ItemVisibility;
import org.scijava.Optional;
import org.scijava.module.AbstractModuleItem;
Expand Down Expand Up @@ -109,7 +110,7 @@ public boolean isRequired() {
}

@Override
public boolean isPersisted() {
public ItemPersistence getPersistence() {
return getParameter().persist();
}

Expand Down
11 changes: 6 additions & 5 deletions src/main/java/org/scijava/module/AbstractModuleItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

import org.scijava.AbstractBasicDetails;
import org.scijava.ItemIO;
import org.scijava.ItemPersistence;
import org.scijava.ItemVisibility;
import org.scijava.util.ClassUtils;
import org.scijava.util.ConversionUtils;
Expand Down Expand Up @@ -71,7 +72,7 @@ public String toString() {
sm.append("description", getDescription());
sm.append("visibility", getVisibility(), ItemVisibility.NORMAL);
sm.append("required", isRequired());
sm.append("persisted", isPersisted());
sm.append("persisted", getPersistence());
sm.append("persistKey", getPersistKey());
sm.append("callback", getCallback());
sm.append("widgetStyle", getWidgetStyle());
Expand Down Expand Up @@ -131,8 +132,8 @@ public boolean isRequired() {
}

@Override
public boolean isPersisted() {
return true;
public ItemPersistence getPersistence() {
return ItemPersistence.DEFAULT;
}

@Override
Expand All @@ -149,7 +150,7 @@ public String getPersistKey() {
@Deprecated
public T loadValue() {
// if there is nothing to load from persistence return nothing
if (!isPersisted()) return null;
if (getPersistence() == ItemPersistence.NO) return null;

final String sValue;
final String persistKey = getPersistKey();
Expand All @@ -169,7 +170,7 @@ public T loadValue() {
@Override
@Deprecated
public void saveValue(final T value) {
if (!isPersisted()) return;
if (getPersistence() == ItemPersistence.NO) return;

final String sValue = value == null ? "" : value.toString();

Expand Down
14 changes: 11 additions & 3 deletions src/main/java/org/scijava/module/DefaultModuleService.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import java.util.concurrent.Future;

import org.scijava.Identifiable;
import org.scijava.ItemPersistence;
import org.scijava.MenuPath;
import org.scijava.Priority;
import org.scijava.convert.ConvertService;
Expand Down Expand Up @@ -289,9 +290,16 @@ public ModuleItem<?> getSingleOutput(Module module, Collection<Class<?>> types)

@Override
public <T> void save(final ModuleItem<T> item, final T value) {
if (!item.isPersisted()) return;
ItemPersistence persistence = item.getPersistence();

if (MiscUtils.equal(item.getDefaultValue(), value)) {
if (persistence == ItemPersistence.NO) return;

// NB: Do not persist values which are computed via an initializer.
if (item.getInitializer() != null && !item.getInitializer().isEmpty() &&
persistence == ItemPersistence.DEFAULT) return;

if (MiscUtils.equal(item.getDefaultValue(), value) &&
persistence == ItemPersistence.DEFAULT) {
// NB: Do not persist the value if it is the default.
// This is nice if the default value might change later,
// such as when iteratively developing a script.
Expand All @@ -315,7 +323,7 @@ public <T> void save(final ModuleItem<T> item, final T value) {
@Override
public <T> T load(final ModuleItem<T> item) {
// if there is nothing to load from persistence return nothing
if (!item.isPersisted()) return null;
if (item.getPersistence() == ItemPersistence.NO) return null;

final String sValue;
final String persistKey = item.getPersistKey();
Expand Down
15 changes: 8 additions & 7 deletions src/main/java/org/scijava/module/DefaultMutableModuleItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import java.util.List;

import org.scijava.ItemIO;
import org.scijava.ItemPersistence;
import org.scijava.ItemVisibility;

/**
Expand All @@ -54,7 +55,7 @@ public class DefaultMutableModuleItem<T> extends AbstractModuleItem<T>
private ItemIO ioType;
private ItemVisibility visibility;
private boolean required;
private boolean persisted;
private ItemPersistence persistence;
private String persistKey;
private String initializer;
private String callback;
Expand Down Expand Up @@ -87,7 +88,7 @@ public DefaultMutableModuleItem(final ModuleInfo info, final String name,
ioType = super.getIOType();
visibility = super.getVisibility();
required = super.isRequired();
persisted = super.isPersisted();
persistence = super.getPersistence();
persistKey = super.getPersistKey();
initializer = super.getInitializer();
callback = super.getCallback();
Expand All @@ -113,7 +114,7 @@ public DefaultMutableModuleItem(final ModuleInfo info,
ioType = item.getIOType();
visibility = item.getVisibility();
required = item.isRequired();
persisted = item.isPersisted();
persistence = item.getPersistence();
persistKey = item.getPersistKey();
initializer = item.getInitializer();
callback = item.getCallback();
Expand Down Expand Up @@ -148,8 +149,8 @@ public void setRequired(final boolean required) {
}

@Override
public void setPersisted(final boolean persisted) {
this.persisted = persisted;
public void setPersistence(final ItemPersistence persistence) {
this.persistence = persistence;
}

@Override
Expand Down Expand Up @@ -241,8 +242,8 @@ public boolean isRequired() {
}

@Override
public boolean isPersisted() {
return persisted;
public ItemPersistence getPersistence() {
return persistence;
}

@Override
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/org/scijava/module/ModuleItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

import org.scijava.BasicDetails;
import org.scijava.ItemIO;
import org.scijava.ItemPersistence;
import org.scijava.ItemVisibility;

/**
Expand Down Expand Up @@ -84,7 +85,7 @@ public interface ModuleItem<T> extends BasicDetails {
boolean isRequired();

/** Gets whether to remember the most recent value of the parameter. */
boolean isPersisted();
ItemPersistence getPersistence();

/** Gets the key to use for saving the value persistently. */
String getPersistKey();
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/org/scijava/module/MutableModuleItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import java.util.List;

import org.scijava.ItemIO;
import org.scijava.ItemPersistence;
import org.scijava.ItemVisibility;

/**
Expand All @@ -50,7 +51,7 @@ public interface MutableModuleItem<T> extends ModuleItem<T> {

void setRequired(boolean required);

void setPersisted(boolean persisted);
void setPersistence(ItemPersistence persistence);

void setPersistKey(String persistKey);

Expand Down
10 changes: 8 additions & 2 deletions src/main/java/org/scijava/plugin/Parameter.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import java.lang.annotation.Target;

import org.scijava.ItemIO;
import org.scijava.ItemPersistence;
import org.scijava.ItemVisibility;

/**
Expand Down Expand Up @@ -111,12 +112,17 @@
boolean required() default true;

/** Defines whether to remember the most recent value of the parameter. */
boolean persist() default true;
ItemPersistence persist() default ItemPersistence.DEFAULT;

/** Defines a key to use for saving the value persistently. */
String persistKey() default "";

/** Defines a function that is called to initialize the parameter. */
/**
* Defines a function that is called to initialize the parameter. If an
* initializer is defined, it takes precedence over {@link #persist()}, i.e.
* the parameter is not persisted even if {@link #persist()} returns
* {@link ItemPersistence#YES}.
*/
String initializer() default "";

/**
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/org/scijava/script/ScriptInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import org.scijava.Context;
import org.scijava.Contextual;
import org.scijava.ItemIO;
import org.scijava.ItemPersistence;
import org.scijava.ItemVisibility;
import org.scijava.NullContextException;
import org.scijava.command.Command;
Expand Down Expand Up @@ -427,7 +428,7 @@ private <T> void assignAttribute(final DefaultMutableModuleItem<T> item,
else if (is(k, "max")) item.setMaximumValue(as(v, item.getType()));
else if (is(k, "min")) item.setMinimumValue(as(v, item.getType()));
else if (is(k, "name")) item.setName(as(v, String.class));
else if (is(k, "persist")) item.setPersisted(as(v, boolean.class));
else if (is(k, "persist")) item.setPersistence(as(v, ItemPersistence.class));
else if (is(k, "persistKey")) item.setPersistKey(as(v, String.class));
else if (is(k, "required")) item.setRequired(as(v, boolean.class));
else if (is(k, "softMax")) item.setSoftMaximum(as(v, item.getType()));
Expand Down
58 changes: 51 additions & 7 deletions src/test/java/org/scijava/module/ModuleServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@

package org.scijava.module;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;

import org.junit.Test;
import org.scijava.Context;
import org.scijava.prefs.PrefService;

/**
* Tests {@link ModuleService}.
Expand Down Expand Up @@ -74,6 +76,38 @@ public void testGetSingleInput() throws ModuleException {
assertSame(info.getInput("double2"), singleDouble);
}

@SuppressWarnings("unchecked")
@Test
public void testPersistingWithInitialize() {
final Context context = new Context(ModuleService.class, PrefService.class);
final ModuleService moduleService = context.getService(ModuleService.class);

// reset the PrefService entries for the test
final PrefService prefService = context.getService(PrefService.class);
prefService.clear("persistInteger");
prefService.clear("persistDouble");

final ModuleInfo info = new FooModuleInfo();
final ModuleItem<Double> doubleItem = (ModuleItem<Double>) info.getInput(
"double1");
final ModuleItem<Integer> integerItem = (ModuleItem<Integer>) info.getInput(
"integer1");

// save ModuleItem for which getInitializer() returns "testInitializer"
moduleService.save(doubleItem, 5d);

// verify that the item is not persisted
String persistKey = doubleItem.getPersistKey();
assertNull(prefService.get(persistKey));

// save ModuleItem for which getInitializer() returns null
moduleService.save(integerItem, 5);

// verify that the item is persisted
persistKey = integerItem.getPersistKey();
assertEquals(5, prefService.getInt(persistKey, 0));
}

/** A sample module for testing the module service. */
public static class FooModule extends AbstractModule {

Expand Down Expand Up @@ -115,16 +149,16 @@ public Module createModule() throws ModuleException {

@Override
protected void parseParameters() {
addInput("string", String.class, true);
addInput("float", Float.class, false);
addInput("integer1", Integer.class, true);
addInput("integer2", Integer.class, true);
addInput("double1", Double.class, false);
addInput("double2", Double.class, true);
addInput("string", String.class, true, null, null);
addInput("float", Float.class, false, null, null);
addInput("integer1", Integer.class, true, "persistInteger", null);
addInput("integer2", Integer.class, true, null, null);
addInput("double1", Double.class, false, "persistDouble", "testInitializer");
addInput("double2", Double.class, true, null, null);
}

private <T> void addInput(final String name, final Class<T> type,
final boolean autoFill)
final boolean autoFill, final String persistKey, final String initializer)
{
registerInput(new AbstractModuleItem<T>(this) {

Expand All @@ -143,6 +177,16 @@ public boolean isAutoFill() {
return autoFill;
}

@Override
public String getPersistKey() {
return persistKey;
}

@Override
public String getInitializer() {
return initializer;
}

});
}

Expand Down
Loading