You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2013/06/07 16:40:07 UTC

[1/2] git commit: ISIS-426: improved assertion messages for ComparableContractTester

Updated Branches:
  refs/heads/master 51586b75a -> ee10fcfbb


ISIS-426: improved assertion messages for ComparableContractTester


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/c04a9630
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/c04a9630
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/c04a9630

Branch: refs/heads/master
Commit: c04a9630fef419e004a777849f30e1dc10487f66
Parents: 51586b7
Author: Dan Haywood <da...@apache.org>
Authored: Fri Jun 7 08:21:06 2013 +0100
Committer: Dan Haywood <da...@apache.org>
Committed: Fri Jun 7 08:21:06 2013 +0100

----------------------------------------------------------------------
 .../comparable/ComparableContractTester.java       |   19 +++++++++++----
 1 files changed, 14 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/c04a9630/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/comparable/ComparableContractTester.java
----------------------------------------------------------------------
diff --git a/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/comparable/ComparableContractTester.java b/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/comparable/ComparableContractTester.java
index cbfdbd5..f6a894b 100644
--- a/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/comparable/ComparableContractTester.java
+++ b/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/comparable/ComparableContractTester.java
@@ -33,16 +33,25 @@ public class ComparableContractTester<T extends Comparable<T>> {
             T item3 = orderedTuple.get(2);
             T item4 = orderedTuple.get(3);
 
-            assertThat(item1.compareTo(item2), is(Matchers.lessThan(0)));
-            assertThat(item2.compareTo(item1), is(Matchers.greaterThan(0)));
+            assertThat(desc(item1, "<", item2), item1.compareTo(item2), is(Matchers.lessThan(0)));
+            assertThat(desc(item2, ">", item1), item2.compareTo(item1), is(Matchers.greaterThan(0)));
             
-            assertThat(item2.compareTo(item3), is(0));
+            assertThat(desc(item2, "==", item3), item2.compareTo(item3), is(0));
+            assertThat(desc(item3, "==", item2), item3.compareTo(item2), is(0));
             
-            assertThat(item3.compareTo(item4), is(Matchers.lessThan(0)));
-            assertThat(item4.compareTo(item3), is(Matchers.greaterThan(0)));
+            assertThat(desc(item3, "<", item4), item3.compareTo(item4), is(Matchers.lessThan(0)));
+            assertThat(desc(item4, ">", item3), item4.compareTo(item3), is(Matchers.greaterThan(0)));
         }
     }
 
+    protected static String desc(Object item1, final String op, Object item2) {
+        return nullSafe(item1) + op + nullSafe(item2);
+    }
+
+    private static String nullSafe(Object item) {
+        return item != null? item.toString(): "null";
+    }
+
     /**
      * Syntax sugar to remove boilerplate from subclasses.
      */


[2/2] git commit: ISIS-427: settings services.

Posted by da...@apache.org.
ISIS-427: settings services.


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/ee10fcfb
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/ee10fcfb
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/ee10fcfb

Branch: refs/heads/master
Commit: ee10fcfbb7ddb6b469354483662cd9bc83e043d4
Parents: c04a963
Author: Dan Haywood <da...@apache.org>
Authored: Fri Jun 7 15:39:49 2013 +0100
Committer: Dan Haywood <da...@apache.org>
Committed: Fri Jun 7 15:39:49 2013 +0100

----------------------------------------------------------------------
 .../service/settings/ApplicationSettingJdo.java    |   73 ++++++
 .../settings/ApplicationSettingsServiceJdo.java    |  111 +++++++++
 .../service/settings/SettingAbstractJdo.java       |  187 ++++++++++++++
 .../applib/service/settings/UserSettingJdo.java    |  102 ++++++++
 .../service/settings/UserSettingPrimaryKey.java    |   90 +++++++
 .../service/settings/UserSettingsServiceJdo.java   |  168 +++++++++++++
 component/objectstore/jdo/pom.xml                  |    2 +-
 component/security/file/pom.xml                    |    2 +-
 component/security/shiro/pom.xml                   |    2 +-
 component/viewer/restfulobjects/pom.xml            |    2 +-
 component/viewer/wicket/pom.xml                    |    2 +-
 .../widgets/entitylink/EntityLinkSelect2Panel.java |    4 +-
 .../services/settings/ApplicationSetting.java      |   25 ++
 .../settings/ApplicationSettingsService.java       |   27 ++
 .../isis/applib/services/settings/Setting.java     |   53 ++++
 .../applib/services/settings/SettingAbstract.java  |  192 +++++++++++++++
 .../isis/applib/services/settings/SettingType.java |   28 ++
 .../isis/applib/services/settings/UserSetting.java |   34 +++
 .../services/settings/UserSettingsService.java     |   27 ++
 .../services/settings/SettingAbstractTest.java     |  106 ++++++++
 .../quickstart_wicket_restful_jdo/pom.xml          |    6 +-
 .../webapp/src/main/webapp/WEB-INF/isis.properties |    6 +
 22 files changed, 1240 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/ee10fcfb/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/settings/ApplicationSettingJdo.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/settings/ApplicationSettingJdo.java b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/settings/ApplicationSettingJdo.java
new file mode 100644
index 0000000..8e726c2
--- /dev/null
+++ b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/settings/ApplicationSettingJdo.java
@@ -0,0 +1,73 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.objectstore.jdo.applib.service.settings;
+
+import javax.jdo.annotations.IdentityType;
+import javax.jdo.annotations.Persistent;
+
+import org.apache.isis.applib.annotation.Named;
+import org.apache.isis.applib.services.settings.ApplicationSetting;
+import org.apache.isis.applib.services.settings.SettingType;
+
+@javax.jdo.annotations.PersistenceCapable(identityType = IdentityType.APPLICATION, table="APPLICATION_SETTING")
+@javax.jdo.annotations.Queries({ 
+     @javax.jdo.annotations.Query(name = "applicationsetting_by_id", language = "JDOQL", value = "SELECT FROM org.apache.isis.objectstore.jdo.applib.service.settings.ApplicationSettingJdo WHERE key == :key") 
+    ,@javax.jdo.annotations.Query(name = "applicationsetting_all", language = "JDOQL", value = "SELECT FROM org.apache.isis.objectstore.jdo.applib.service.settings.ApplicationSettingJdo ORDER BY key") 
+})
+@Named("Application Setting")
+public class ApplicationSettingJdo extends SettingAbstractJdo implements ApplicationSetting {
+
+    @javax.jdo.annotations.PrimaryKey
+    public String getKey() {
+        return super.getKey();
+    }
+    @Override
+    public void setKey(String key) {
+        super.setKey(key);
+    }
+
+    @Persistent
+    @Override
+    public String getDescription() {
+        return super.getDescription();
+    }
+    @Override
+    public void setDescription(String description) {
+        super.setDescription(description);
+    }
+    @Persistent
+    @Override
+    public String getValueRaw() {
+        return super.getValueRaw();
+    }
+    @Override
+    public void setValueRaw(String valueAsRaw) {
+        super.setValueRaw(valueAsRaw);
+    }
+    @Persistent
+    @Override
+    public SettingType getType() {
+        return super.getType();
+    }
+    @Override
+    public void setType(SettingType type) {
+        super.setType(type);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/ee10fcfb/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/settings/ApplicationSettingsServiceJdo.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/settings/ApplicationSettingsServiceJdo.java b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/settings/ApplicationSettingsServiceJdo.java
new file mode 100644
index 0000000..aae1a2d
--- /dev/null
+++ b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/settings/ApplicationSettingsServiceJdo.java
@@ -0,0 +1,111 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.objectstore.jdo.applib.service.settings;
+
+import java.util.List;
+
+import org.joda.time.LocalDate;
+
+import org.apache.isis.applib.AbstractService;
+import org.apache.isis.applib.annotation.Hidden;
+import org.apache.isis.applib.annotation.MemberOrder;
+import org.apache.isis.applib.annotation.Named;
+import org.apache.isis.applib.annotation.Optional;
+import org.apache.isis.applib.query.QueryDefault;
+import org.apache.isis.applib.services.settings.ApplicationSetting;
+import org.apache.isis.applib.services.settings.ApplicationSettingsService;
+import org.apache.isis.applib.services.settings.SettingAbstract;
+import org.apache.isis.applib.services.settings.SettingType;
+
+/**
+ * An implementation of {@link ApplicationSettingsService} that persists settings
+ * as entities into a JDO-backed database.
+ */
+@Named("Application Settings")
+public class ApplicationSettingsServiceJdo extends AbstractService implements ApplicationSettingsService {
+
+    @Hidden
+    @Override
+    public ApplicationSetting find(@Named("Key") String key) {
+        return firstMatch(
+                new QueryDefault<ApplicationSettingJdo>(ApplicationSettingJdo.class, 
+                        "applicationsetting_by_id", 
+                        "key", key));
+    }
+
+    // //////////////////////////////////////
+
+    @MemberOrder(sequence="1")
+    public List<ApplicationSettingJdo> listAll() {
+        return allMatches(
+                new QueryDefault<ApplicationSettingJdo>(ApplicationSettingJdo.class, 
+                        "applicationsetting_all"));
+    }
+
+    // //////////////////////////////////////
+
+    @MemberOrder(sequence="10")
+    public ApplicationSettingJdo newString(
+            @Named("Key") String key, 
+            @Named("Description") @Optional String description, 
+            @Named("Value") String value) {
+        return newSetting(key, description, SettingType.STRING, value);
+    }
+    @MemberOrder(sequence="11")
+    public ApplicationSettingJdo newInt(
+            @Named("Key") String key, 
+            @Named("Description") @Optional String description, 
+            @Named("Value") int value) {
+        return newSetting(key, description, SettingType.INT, new Integer(value).toString());
+    }
+    @MemberOrder(sequence="12")
+    public ApplicationSettingJdo newLong(
+            @Named("Key") String key, 
+            @Named("Description") @Optional String description, 
+            @Named("Value") long value) {
+        return newSetting(key, description, SettingType.LONG, new Long(value).toString());
+    }
+    @MemberOrder(sequence="13")
+    public ApplicationSettingJdo newLocalDate(
+            @Named("Key") String key, 
+            @Named("Description") @Optional String description, 
+            @Named("Value") LocalDate value) {
+        return newSetting(key, description, SettingType.LOCAL_DATE, value.toString(SettingAbstract.DATE_FORMATTER));
+    }
+    @MemberOrder(sequence="14")
+    public ApplicationSettingJdo newBoolean(
+            @Named("Key") String key, 
+            @Named("Description") @Optional String description, 
+            @Named("Value") @Optional Boolean value) {
+        return newSetting(key, description, SettingType.BOOLEAN, new Boolean(value != null && value).toString());
+    }
+
+    private ApplicationSettingJdo newSetting(
+            String key, String description, SettingType settingType, final String valueRaw) {
+        final ApplicationSettingJdo setting = newTransientInstance(ApplicationSettingJdo.class);
+        setting.setKey(key);
+        setting.setDescription(description);
+        setting.setValueRaw(valueRaw);
+        setting.setType(settingType);
+        persist(setting);
+        return setting;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/ee10fcfb/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/settings/SettingAbstractJdo.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/settings/SettingAbstractJdo.java b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/settings/SettingAbstractJdo.java
new file mode 100644
index 0000000..c79cb92
--- /dev/null
+++ b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/settings/SettingAbstractJdo.java
@@ -0,0 +1,187 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.objectstore.jdo.applib.service.settings;
+
+import javax.jdo.annotations.PersistenceCapable;
+
+import org.joda.time.LocalDate;
+
+import org.apache.isis.applib.DomainObjectContainer;
+import org.apache.isis.applib.annotation.MemberOrder;
+import org.apache.isis.applib.annotation.Named;
+import org.apache.isis.applib.annotation.Optional;
+import org.apache.isis.applib.services.settings.SettingType;
+
+/**
+ * Factors out common implementation; however this is annotated with {@link PersistenceCapable},
+ * so that each subclass is its own root entity.
+ */
+public abstract class SettingAbstractJdo extends org.apache.isis.applib.services.settings.SettingAbstract implements org.apache.isis.applib.services.settings.ApplicationSetting {
+
+    private String key;
+
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(final String key) {
+        this.key = key;
+    }
+
+    // //////////////////////////////////////
+
+    private String description;
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(final String description) {
+        this.description = description;
+    }
+
+    @MemberOrder(name="Description", sequence="1")
+    @Named("Update")
+    public SettingAbstractJdo updateDescription(@Named("Description") @Optional String description) {
+        setDescription(description);
+        return this;
+    }
+    public String default0UpdateDescription() {
+        return getDescription();
+    }
+    
+    // //////////////////////////////////////
+
+    private SettingType type;
+
+    public SettingType getType() {
+        return type;
+    }
+
+    public void setType(final SettingType type) {
+        this.type = type;
+    }
+
+    // //////////////////////////////////////
+
+    private String valueRaw;
+
+    public String getValueRaw() {
+        return valueRaw;
+    }
+
+    public void setValueRaw(final String valueAsRaw) {
+        this.valueRaw = valueAsRaw;
+    }
+
+    // //////////////////////////////////////
+    
+    @MemberOrder(name="ValueAsString", sequence="1")
+    @Named("Update")
+    public SettingAbstractJdo updateAsString(@Named("Value") String value) {
+        setValueRaw(value);
+        return this;
+    }
+    public String default0UpdateAsString() {
+        return getValueAsString();
+    }
+    public boolean hideUpdateAsString() {
+        return typeIsNot(SettingType.STRING);
+    }
+    
+    @MemberOrder(name="ValueAsInt", sequence="1")
+    @Named("Update")
+    public SettingAbstractJdo updateAsInt(@Named("Value") Integer value) {
+        setValueRaw(value.toString());
+        return this;
+    }
+    public Integer default0UpdateAsInt() {
+        return getValueAsInt();
+    }
+    public boolean hideUpdateAsInt() {
+        return typeIsNot(SettingType.INT);
+    }
+    
+    @MemberOrder(name="ValueAsLong", sequence="1")
+    @Named("Update")
+    public SettingAbstractJdo updateAsLong(@Named("Value") Long value) {
+        setValueRaw(value.toString());
+        return this;
+    }
+    public Long default0UpdateAsLong() {
+        return getValueAsLong();
+    }
+    public boolean hideUpdateAsLong() {
+        return typeIsNot(SettingType.LONG);
+    }
+    
+    @MemberOrder(name="ValueAsLocalDate", sequence="1")
+    @Named("Update")
+    public SettingAbstractJdo updateAsLocalDate(@Named("Value") LocalDate value) {
+        setValueRaw(value.toString(DATE_FORMATTER));
+        return this;
+    }
+    public LocalDate default0UpdateAsLocalDate() {
+        return getValueAsLocalDate();
+    }
+    public boolean hideUpdateAsLocalDate() {
+        return typeIsNot(SettingType.LOCAL_DATE);
+    }
+
+    @MemberOrder(name="ValueAsBoolean", sequence="1")
+    @Named("Update")
+    public SettingAbstractJdo updateAsBoolean(@Named("Value") Boolean value) {
+        setValueRaw(value.toString());
+        return this;
+    }
+    public Boolean default0UpdateAsBoolean() {
+        return getValueAsBoolean();
+    }
+    public boolean hideUpdateAsBoolean() {
+        return typeIsNot(SettingType.BOOLEAN);
+    }
+    
+    // //////////////////////////////////////
+    
+    
+    public SettingAbstractJdo delete(
+            @Named("Are you sure?") @Optional Boolean confirm) {
+        if(confirm == null || !confirm) {
+            container.informUser("Setting NOT deleted");
+            return this;
+        }
+        container.remove(this);
+        container.informUser("Setting deleted");
+        return null;
+    }
+    
+
+    
+ 
+    // //////////////////////////////////////
+    
+    private DomainObjectContainer container;
+
+    public void setDomainObjectContainer(final DomainObjectContainer container) {
+        this.container = container;
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/ee10fcfb/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/settings/UserSettingJdo.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/settings/UserSettingJdo.java b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/settings/UserSettingJdo.java
new file mode 100644
index 0000000..cd7ba63
--- /dev/null
+++ b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/settings/UserSettingJdo.java
@@ -0,0 +1,102 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.objectstore.jdo.applib.service.settings;
+
+
+import javax.jdo.annotations.IdentityType;
+import javax.jdo.annotations.Persistent;
+import javax.jdo.annotations.PrimaryKey;
+
+import org.apache.isis.applib.annotation.MemberOrder;
+import org.apache.isis.applib.annotation.Named;
+import org.apache.isis.applib.annotation.Title;
+import org.apache.isis.applib.services.settings.SettingType;
+import org.apache.isis.applib.services.settings.UserSetting;
+
+@javax.jdo.annotations.PersistenceCapable(identityType = IdentityType.APPLICATION, table="USER_SETTING", objectIdClass=UserSettingPrimaryKey.class)
+@javax.jdo.annotations.Queries({ 
+    @javax.jdo.annotations.Query(name = "usersetting_by_id", language = "JDOQL", value = "SELECT FROM org.apache.isis.objectstore.jdo.applib.service.settings.UserSettingJdo WHERE user == :user AND key == :key ") 
+    ,@javax.jdo.annotations.Query(name = "usersetting_by_user", language = "JDOQL", value = "SELECT FROM org.apache.isis.objectstore.jdo.applib.service.settings.UserSettingJdo WHERE user == :user ORDER BY key") 
+    ,@javax.jdo.annotations.Query(name = "usersetting_all", language = "JDOQL", value = "SELECT FROM org.apache.isis.objectstore.jdo.applib.service.settings.UserSettingJdo ORDER BY user, key") 
+})
+// can't see how to specify this order in the primary key; however HSQLDB objects :-(
+//@javax.jdo.annotations.Unique(name="USER_KEY_IDX", members={"user","key"}) 
+@Named("User Setting")
+public class UserSettingJdo extends SettingAbstractJdo implements UserSetting {
+
+    
+    private String user;
+
+    @Title(sequence="5", append=": ")
+    @PrimaryKey
+    @MemberOrder(sequence = "5")
+    public String getUser() {
+        return user;
+    }
+
+    public void setUser(final String user) {
+        this.user = user;
+    }
+
+    @Title(sequence="10")
+    @PrimaryKey
+    @Override
+    public String getKey() {
+        return super.getKey();
+    }
+    @Override
+    public void setKey(String key) {
+        super.setKey(key);
+    }
+
+    
+    @Persistent
+    @Override
+    public String getDescription() {
+        return super.getDescription();
+    }
+    @Override
+    public void setDescription(String description) {
+        super.setDescription(description);
+    }
+    
+    @Title(prepend=" = ", sequence="30")
+    @Persistent
+    @Override
+    public String getValueRaw() {
+        return super.getValueRaw();
+    }
+    @Persistent
+    @Override
+    public void setValueRaw(String valueAsRaw) {
+        super.setValueRaw(valueAsRaw);
+    }
+    @Persistent
+    @Override
+    public SettingType getType() {
+        return super.getType();
+    }
+    @Override
+    public void setType(SettingType type) {
+        super.setType(type);
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/ee10fcfb/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/settings/UserSettingPrimaryKey.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/settings/UserSettingPrimaryKey.java b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/settings/UserSettingPrimaryKey.java
new file mode 100644
index 0000000..423ac25
--- /dev/null
+++ b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/settings/UserSettingPrimaryKey.java
@@ -0,0 +1,90 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.isis.objectstore.jdo.applib.service.settings;
+
+import java.io.Serializable;
+import java.util.StringTokenizer;
+
+/**
+ * @see http://www.datanucleus.org/products/datanucleus/jdo/primary_key.html
+ */
+public class UserSettingPrimaryKey implements Serializable
+{
+    private static final long serialVersionUID = 1L;
+
+    
+    public String user;
+    public String key;
+    
+    public UserSettingPrimaryKey ()
+    {
+    }
+
+    public String getUser() {
+        return user;
+    }
+
+    public void setUser(String user) {
+        this.user = user;
+    }
+
+    public String getKey() {
+        return key;
+    }
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+
+    /**
+     * Constructor accepting same input as generated by toString().
+     */
+    public UserSettingPrimaryKey(String value) 
+    {
+        StringTokenizer token = new StringTokenizer (value, ";;");
+        token.nextToken();               // className
+        this.setUser(token.nextToken());   // user
+        this.setKey(token.nextToken());    // key
+    }
+
+    public boolean equals(Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (!(obj instanceof UserSettingPrimaryKey))
+        {
+            return false;
+        }
+        UserSettingPrimaryKey c = (UserSettingPrimaryKey)obj;
+
+        return getUser().equals(c.getUser()) && getKey().equals(c.getKey());
+    }
+
+    public int hashCode ()
+    {
+        return this.getUser().hashCode() ^ this.getKey().hashCode();
+    }
+
+    public String toString ()
+    {
+        // Give output expected by String constructor
+        return this.getClass().getName() + ";;"  + this.getUser() + ";;" + this.getKey();
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/ee10fcfb/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/settings/UserSettingsServiceJdo.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/settings/UserSettingsServiceJdo.java b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/settings/UserSettingsServiceJdo.java
new file mode 100644
index 0000000..a269699
--- /dev/null
+++ b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/settings/UserSettingsServiceJdo.java
@@ -0,0 +1,168 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.objectstore.jdo.applib.service.settings;
+
+import java.util.List;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+import org.joda.time.LocalDate;
+
+import org.apache.isis.applib.AbstractService;
+import org.apache.isis.applib.annotation.Hidden;
+import org.apache.isis.applib.annotation.MemberOrder;
+import org.apache.isis.applib.annotation.Named;
+import org.apache.isis.applib.annotation.Optional;
+import org.apache.isis.applib.query.QueryDefault;
+import org.apache.isis.applib.services.settings.SettingAbstract;
+import org.apache.isis.applib.services.settings.SettingType;
+import org.apache.isis.applib.services.settings.UserSetting;
+import org.apache.isis.applib.services.settings.UserSettingsService;
+
+/**
+ * An implementation of {@link UserSettingsService} that persists settings
+ * as entities into a JDO-backed database.
+ */
+@Named("User Settings")
+public class UserSettingsServiceJdo extends AbstractService implements UserSettingsService {
+
+    @Hidden
+    @Override
+    public UserSetting find(
+            @Named("User") String user, 
+            @Named("Key") String key) {
+        return firstMatch(
+                new QueryDefault<UserSettingJdo>(UserSettingJdo.class, 
+                        "usersetting_by_id", 
+                        "user",user,
+                        "key", key));
+    }
+
+    // //////////////////////////////////////
+
+    @MemberOrder(sequence="1")
+    public List<UserSettingJdo> listAll() {
+        return allMatches(
+                new QueryDefault<UserSettingJdo>(UserSettingJdo.class, 
+                        "usersetting_all"));
+    }
+
+    @MemberOrder(sequence="1")
+    public List<UserSettingJdo> listAllFor(@Named("User") String user) {
+        return allMatches(
+                new QueryDefault<UserSettingJdo>(UserSettingJdo.class, 
+                        "usersetting_by_user", 
+                        "user", user));
+    }
+    public List<String> choices0ListAllFor() {
+        return existingUsers();
+    }
+
+    private List<String> existingUsers() {
+        final List<UserSettingJdo> listAll = listAll();
+        return Lists.newArrayList(Sets.newTreeSet(Iterables.transform(listAll, GET_USER)));
+    }
+
+    private final static Function<UserSettingJdo, String> GET_USER = new Function<UserSettingJdo, String>() {
+        public String apply(UserSettingJdo input) {
+            return input.getUser();
+        }
+    };
+
+
+    // //////////////////////////////////////
+    
+    @MemberOrder(sequence="10")
+    public UserSettingJdo newString(
+            @Named("User") String user, 
+            @Named("Key") String key, 
+            @Named("Description") @Optional String description, 
+            @Named("Value") String value) {
+        return newSetting(user, key, description, SettingType.STRING, value);
+    }
+    public String default0NewString() {
+        return getContainer().getUser().getName();
+    }
+
+    @MemberOrder(sequence="11")
+    public UserSettingJdo newInt(
+            @Named("User") String user, 
+            @Named("Key") String key, 
+            @Named("Description") @Optional String description, 
+            @Named("Value") Integer value) {
+        return newSetting(user, key, description, SettingType.INT, value.toString());
+    }
+    public String default0NewInt() {
+        return getContainer().getUser().getName();
+    }
+
+    @MemberOrder(sequence="12")
+    public UserSettingJdo newLong(
+            @Named("User") String user, 
+            @Named("Key") String key, 
+            @Named("Description") @Optional String description, 
+            @Named("Value") Long value) {
+        return newSetting(user, key, description, SettingType.LONG, value.toString());
+    }
+    public String default0NewLong() {
+        return getContainer().getUser().getName();
+    }
+
+    @MemberOrder(sequence="13")
+    public UserSettingJdo newLocalDate(
+            @Named("User") String user, 
+            @Named("Key") String key, 
+            @Named("Description") @Optional String description, 
+            @Named("Value") LocalDate value) {
+        return newSetting(user, key, description, SettingType.LOCAL_DATE, value.toString(SettingAbstract.DATE_FORMATTER));
+    }
+    public String default0NewLocalDate() {
+        return getContainer().getUser().getName();
+    }
+
+    @MemberOrder(sequence="14")
+    public UserSettingJdo newBoolean(
+            @Named("User") String user, 
+            @Named("Key") String key, 
+            @Named("Description") @Optional String description, 
+            @Named("Value") @Optional Boolean value) {
+        return newSetting(user, key, description, SettingType.BOOLEAN, new Boolean(value != null && value).toString());
+    }
+    public String default0NewBoolean() {
+        return getContainer().getUser().getName();
+    }
+
+    private UserSettingJdo newSetting(
+            String user, String key, String description, SettingType settingType, final String valueRaw) {
+        final UserSettingJdo setting = newTransientInstance(UserSettingJdo.class);
+        setting.setUser(user);
+        setting.setKey(key);
+        setting.setType(settingType);
+        setting.setDescription(description);
+        setting.setValueRaw(valueRaw);
+        persist(setting);
+        return setting;
+    }
+    
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/ee10fcfb/component/objectstore/jdo/pom.xml
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/pom.xml b/component/objectstore/jdo/pom.xml
index 7f70e23..8ab88db 100644
--- a/component/objectstore/jdo/pom.xml
+++ b/component/objectstore/jdo/pom.xml
@@ -16,7 +16,7 @@
 	<parent>
 		<groupId>org.apache.isis.core</groupId>
 		<artifactId>isis</artifactId>
-        <version>1.2.0</version>
+        <version>1.3.0-SNAPSHOT</version>
 		<relativePath>../../../core/pom.xml</relativePath>
 	</parent>
 

http://git-wip-us.apache.org/repos/asf/isis/blob/ee10fcfb/component/security/file/pom.xml
----------------------------------------------------------------------
diff --git a/component/security/file/pom.xml b/component/security/file/pom.xml
index 156f1be..1009462 100644
--- a/component/security/file/pom.xml
+++ b/component/security/file/pom.xml
@@ -23,7 +23,7 @@
 	<parent>
 		<groupId>org.apache.isis.core</groupId>
 		<artifactId>isis</artifactId>
-        <version>1.2.0</version>
+        <version>1.3.0-SNAPSHOT</version>
 		<relativePath>../../../core/pom.xml</relativePath>
 	</parent>
 

http://git-wip-us.apache.org/repos/asf/isis/blob/ee10fcfb/component/security/shiro/pom.xml
----------------------------------------------------------------------
diff --git a/component/security/shiro/pom.xml b/component/security/shiro/pom.xml
index 29935f3..0a13f60 100644
--- a/component/security/shiro/pom.xml
+++ b/component/security/shiro/pom.xml
@@ -23,7 +23,7 @@
 	<parent>
 		<groupId>org.apache.isis.core</groupId>
 		<artifactId>isis</artifactId>
-        <version>1.2.0</version>
+        <version>1.3.0-SNAPSHOT</version>
 		<relativePath>../../../core/pom.xml</relativePath>
 	</parent>
 

http://git-wip-us.apache.org/repos/asf/isis/blob/ee10fcfb/component/viewer/restfulobjects/pom.xml
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/pom.xml b/component/viewer/restfulobjects/pom.xml
index 2b06570..835393a 100644
--- a/component/viewer/restfulobjects/pom.xml
+++ b/component/viewer/restfulobjects/pom.xml
@@ -24,7 +24,7 @@
 	<parent>
 		<groupId>org.apache.isis.core</groupId>
 		<artifactId>isis</artifactId>
-        <version>1.2.0</version>
+        <version>1.3.0-SNAPSHOT</version>
 		<relativePath>../../../core/pom.xml</relativePath>
 	</parent>
 

http://git-wip-us.apache.org/repos/asf/isis/blob/ee10fcfb/component/viewer/wicket/pom.xml
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/pom.xml b/component/viewer/wicket/pom.xml
index 24794ea..3b8eb94 100644
--- a/component/viewer/wicket/pom.xml
+++ b/component/viewer/wicket/pom.xml
@@ -24,7 +24,7 @@
 	<parent>
 		<groupId>org.apache.isis.core</groupId>
 		<artifactId>isis</artifactId>
-        <version>1.2.0</version>
+        <version>1.3.0-SNAPSHOT</version>
 		<relativePath>../../../core/pom.xml</relativePath>
 	</parent>
 

http://git-wip-us.apache.org/repos/asf/isis/blob/ee10fcfb/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitylink/EntityLinkSelect2Panel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitylink/EntityLinkSelect2Panel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitylink/EntityLinkSelect2Panel.java
index 70a4c24..a3b7568 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitylink/EntityLinkSelect2Panel.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitylink/EntityLinkSelect2Panel.java
@@ -27,6 +27,7 @@ import com.google.common.collect.Collections2;
 import com.google.common.collect.Lists;
 import com.vaynberg.wicket.select2.ChoiceProvider;
 import com.vaynberg.wicket.select2.Select2Choice;
+import com.vaynberg.wicket.select2.Settings;
 import com.vaynberg.wicket.select2.TextChoiceProvider;
 
 import org.apache.wicket.Component;
@@ -208,7 +209,8 @@ public class EntityLinkSelect2Panel extends FormComponentPanelAbstract<ObjectAda
             
         };
         autoCompleteField = new Select2Choice<ObjectAdapterMemento>(ID_AUTO_COMPLETE, model, provider);
-        autoCompleteField.getSettings().setMinimumInputLength(MIN_INPUT_LENGTH);
+        final Settings settings = autoCompleteField.getSettings();
+        settings.setMinimumInputLength(MIN_INPUT_LENGTH);
         addOrReplace(autoCompleteField);
         
         // no need for link, since can see in drop-down

http://git-wip-us.apache.org/repos/asf/isis/blob/ee10fcfb/core/applib/src/main/java/org/apache/isis/applib/services/settings/ApplicationSetting.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/settings/ApplicationSetting.java b/core/applib/src/main/java/org/apache/isis/applib/services/settings/ApplicationSetting.java
new file mode 100644
index 0000000..06d4ec1
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/settings/ApplicationSetting.java
@@ -0,0 +1,25 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.isis.applib.services.settings;
+
+
+
+public interface ApplicationSetting extends Setting {
+
+    String getKey();
+    
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/ee10fcfb/core/applib/src/main/java/org/apache/isis/applib/services/settings/ApplicationSettingsService.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/settings/ApplicationSettingsService.java b/core/applib/src/main/java/org/apache/isis/applib/services/settings/ApplicationSettingsService.java
new file mode 100644
index 0000000..1d4c4c3
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/settings/ApplicationSettingsService.java
@@ -0,0 +1,27 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.applib.services.settings;
+
+import org.apache.isis.applib.annotation.Named;
+
+public interface ApplicationSettingsService {
+
+    ApplicationSetting find(@Named("Key") String key);
+    
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/ee10fcfb/core/applib/src/main/java/org/apache/isis/applib/services/settings/Setting.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/settings/Setting.java b/core/applib/src/main/java/org/apache/isis/applib/services/settings/Setting.java
new file mode 100644
index 0000000..3999d4c
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/settings/Setting.java
@@ -0,0 +1,53 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.isis.applib.services.settings;
+
+import org.joda.time.LocalDate;
+
+import org.apache.isis.applib.annotation.MemberOrder;
+
+
+/**
+ * Common supertype for both {@link ApplicationSetting} and {@link UserSetting}.
+ * 
+ * <p>
+ * The difference between the two is in the settings unique identifier; 
+ * the former just is uniquely identified by a single key (defined in 
+ * {@link #getKey() this interface}, whereas the latter is uniquely identified by
+ * the combination of the key plus an identifier of the user.
+ */
+public interface Setting {
+
+    /**
+     * In the case of {@link ApplicationSetting}, this constitutes the unique identifier;
+     * for a {@link UserSetting}, the unique identifier is both this key plus an identifier
+     * for the user.  
+     */
+    String getKey();
+
+    SettingType getType();
+    String getDescription();
+
+    String getValueRaw();
+
+    String valueAsString();
+    LocalDate valueAsLocalDate();
+    Integer valueAsInt();
+    Long valueAsLong();
+    Boolean valueAsBoolean();
+    
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/ee10fcfb/core/applib/src/main/java/org/apache/isis/applib/services/settings/SettingAbstract.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/settings/SettingAbstract.java b/core/applib/src/main/java/org/apache/isis/applib/services/settings/SettingAbstract.java
new file mode 100644
index 0000000..6eb39c8
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/settings/SettingAbstract.java
@@ -0,0 +1,192 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.isis.applib.services.settings;
+
+import org.joda.time.LocalDate;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+
+import org.apache.isis.applib.annotation.Hidden;
+import org.apache.isis.applib.annotation.Immutable;
+import org.apache.isis.applib.annotation.MemberOrder;
+import org.apache.isis.applib.annotation.Named;
+import org.apache.isis.applib.annotation.Optional;
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.annotation.Title;
+import org.apache.isis.applib.annotation.Where;
+
+
+/**
+ * Convenience class to implement {@link Setting}.
+ */
+@Immutable
+public abstract class SettingAbstract implements Setting {
+
+    public final static DateTimeFormatter DATE_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd");
+
+    @Title(sequence="10")
+    @MemberOrder(sequence="10")
+    public abstract String getKey();
+
+    @Optional
+    @MemberOrder(sequence="80")
+    public abstract String getDescription();
+
+    @MemberOrder(sequence="90")
+    public abstract SettingType getType();
+
+    // //////////////////////////////////////
+
+    @Title(prepend=" = ", sequence="30")
+    @MemberOrder(sequence="30")
+    @Hidden(where=Where.OBJECT_FORMS)
+    public abstract String getValueRaw();
+
+    // //////////////////////////////////////
+
+    @Programmatic
+    public String valueAsString() {
+        ensure(SettingType.STRING);
+        return getValueRaw();
+    }
+
+    // //////////////////////////////////////
+
+    @Programmatic
+    public LocalDate valueAsLocalDate() {
+        ensure(SettingType.LOCAL_DATE);
+        return parseValueAsLocalDate();
+    }
+
+    protected LocalDate parseValueAsLocalDate() {
+        return LocalDate.parse(getValueRaw(), DATE_FORMATTER);
+    }
+
+    // //////////////////////////////////////
+
+    @Programmatic
+    public Integer valueAsInt() {
+        ensure(SettingType.INT);
+        return parseValueAsInt();
+    }
+
+    protected int parseValueAsInt() {
+        return Integer.parseInt(getValueRaw());
+    }
+
+    // //////////////////////////////////////
+    
+    @Programmatic
+    public Long valueAsLong() {
+        ensure(SettingType.LONG);
+        return parseValueAsLong();
+    }
+    
+    protected long parseValueAsLong() {
+        return Long.parseLong(getValueRaw());
+    }
+    
+    // //////////////////////////////////////
+    
+    @Programmatic
+    public Boolean valueAsBoolean() {
+        ensure(SettingType.BOOLEAN);
+        return parseValueAsBoolean();
+    }
+
+    protected boolean parseValueAsBoolean() {
+        return Boolean.parseBoolean(getValueRaw());
+    }
+
+    // //////////////////////////////////////
+    
+    @MemberOrder(sequence="30")
+    @Hidden(where=Where.ALL_TABLES)
+    @Named("Value")
+    public String getValueAsString() {
+        return getValueRaw();
+    }
+    public boolean hideValueAsString() {
+        return typeIsNot(SettingType.STRING);
+    }
+
+    // //////////////////////////////////////
+    
+    @MemberOrder(sequence="30")
+    @Hidden(where=Where.ALL_TABLES)
+    @Named("Value")
+    public LocalDate getValueAsLocalDate() {
+        return parseValueAsLocalDate();
+    }
+    public boolean hideValueAsLocalDate() {
+        return typeIsNot(SettingType.LOCAL_DATE);
+    }
+    
+    // //////////////////////////////////////
+    
+    
+    @MemberOrder(sequence="30")
+    @Hidden(where=Where.ALL_TABLES)
+    @Named("Value")
+    public Integer getValueAsInt() {
+        return parseValueAsInt();
+    }
+    public boolean hideValueAsInt() {
+        return typeIsNot(SettingType.INT);
+    }
+    
+    // //////////////////////////////////////
+    
+    
+    
+    @MemberOrder(sequence="30")
+    @Hidden(where=Where.ALL_TABLES)
+    @Named("Value")
+    public Long getValueAsLong() {
+        return parseValueAsLong();
+    }
+    public boolean hideValueAsLong() {
+        return typeIsNot(SettingType.LONG);
+    }
+
+    // //////////////////////////////////////
+    
+    
+    
+    @MemberOrder(sequence="30")
+    @Hidden(where=Where.ALL_TABLES)
+    @Named("Value")
+    public Boolean getValueAsBoolean() {
+        return parseValueAsBoolean();
+    }
+    public boolean hideValueAsBoolean() {
+        return typeIsNot(SettingType.BOOLEAN);
+    }
+
+    // //////////////////////////////////////
+
+    private void ensure(SettingType settingType) {
+        if(typeIsNot(settingType)) {
+            throw new IllegalStateException("Setting '" + getKey() + "' is of type " + getType() + ", not of type " + settingType);
+        }
+    }
+    
+    protected boolean typeIsNot(SettingType settingType) {
+        return getType() != settingType;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/ee10fcfb/core/applib/src/main/java/org/apache/isis/applib/services/settings/SettingType.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/settings/SettingType.java b/core/applib/src/main/java/org/apache/isis/applib/services/settings/SettingType.java
new file mode 100644
index 0000000..a652bf3
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/settings/SettingType.java
@@ -0,0 +1,28 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.isis.applib.services.settings;
+
+
+public enum SettingType {
+
+    BOOLEAN,
+    INT,
+    LONG,
+    STRING,
+    LOCAL_DATE
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/ee10fcfb/core/applib/src/main/java/org/apache/isis/applib/services/settings/UserSetting.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/settings/UserSetting.java b/core/applib/src/main/java/org/apache/isis/applib/services/settings/UserSetting.java
new file mode 100644
index 0000000..24ccf65
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/settings/UserSetting.java
@@ -0,0 +1,34 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.isis.applib.services.settings;
+
+import org.apache.isis.applib.DomainObjectContainer;
+import org.apache.isis.applib.security.UserMemento;
+
+
+
+public interface UserSetting extends Setting {
+
+    String getKey();
+    
+    /**
+     * Typically as obtained from the {@link UserMemento#getName() UserMemento} class
+     * (accessible in turn from the {@link DomainObjectContainer#getUser() DomainObjectContainer}).
+     */
+    String getUser();
+    
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/ee10fcfb/core/applib/src/main/java/org/apache/isis/applib/services/settings/UserSettingsService.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/settings/UserSettingsService.java b/core/applib/src/main/java/org/apache/isis/applib/services/settings/UserSettingsService.java
new file mode 100644
index 0000000..24484de
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/settings/UserSettingsService.java
@@ -0,0 +1,27 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.applib.services.settings;
+
+import org.apache.isis.applib.annotation.Named;
+
+public interface UserSettingsService {
+
+    UserSetting find(@Named("User") String user, @Named("Key") String key);
+    
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/ee10fcfb/core/applib/src/test/java/org/apache/isis/applib/services/settings/SettingAbstractTest.java
----------------------------------------------------------------------
diff --git a/core/applib/src/test/java/org/apache/isis/applib/services/settings/SettingAbstractTest.java b/core/applib/src/test/java/org/apache/isis/applib/services/settings/SettingAbstractTest.java
new file mode 100644
index 0000000..cc3191b
--- /dev/null
+++ b/core/applib/src/test/java/org/apache/isis/applib/services/settings/SettingAbstractTest.java
@@ -0,0 +1,106 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.isis.applib.services.settings;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.*;
+
+import org.joda.time.LocalDate;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import org.apache.isis.applib.annotation.Hidden;
+import org.apache.isis.applib.annotation.MemberOrder;
+
+public class SettingAbstractTest {
+
+    @Rule
+    public ExpectedException expectedExceptions = ExpectedException.none();
+
+    private static final class SettingAbstractForTesting extends SettingAbstract {
+        private final String key;
+        private final String valueRaw;
+        private final SettingType type;
+        
+        public SettingAbstractForTesting(String key, String valueRaw, SettingType type) {
+            this.key = key;
+            this.valueRaw = valueRaw;
+            this.type = type;
+        }
+        
+        public String getKey() {
+            return key;
+        }
+
+        public String getValueRaw() {
+            return valueRaw;
+        }
+
+        public SettingType getType() {
+            return type;
+        }
+
+        public String getDescription() {
+            return null;
+        }
+    }
+    
+    private SettingAbstract strSetting;
+    private SettingAbstract intSetting;
+    private SettingAbstract localDateSetting;
+    private SettingAbstract longSetting;
+    private SettingAbstract boolSetting;
+    
+    private LocalDate someLocalDate;
+    
+    @Before
+    public void setUp() throws Exception {
+        someLocalDate = new LocalDate(2012,4,1);
+        
+        strSetting = new SettingAbstractForTesting("strSetting", "ABC", SettingType.STRING);
+        intSetting = new SettingAbstractForTesting("intSetting", "" + Integer.MAX_VALUE, SettingType.INT);
+        localDateSetting = new SettingAbstractForTesting("localDateSetting", someLocalDate.toString(SettingAbstract.DATE_FORMATTER), SettingType.LOCAL_DATE);
+        longSetting = new SettingAbstractForTesting("longSetting", ""+Long.MAX_VALUE, SettingType.LONG);
+        boolSetting = new SettingAbstractForTesting("boolSetting", Boolean.TRUE.toString(), SettingType.BOOLEAN);
+    }
+    
+    @Test
+    public void happyCases() {
+        assertThat(strSetting.valueAsString(), is("ABC"));
+        assertThat(intSetting.valueAsInt(), is(Integer.MAX_VALUE));
+        assertThat(localDateSetting.valueAsLocalDate(), is(someLocalDate));
+        assertThat(longSetting.valueAsLong(), is(Long.MAX_VALUE));
+        assertThat(boolSetting.valueAsBoolean(), is(true));
+    }
+
+    @Test
+    public void sadCases() {
+        expectedExceptions.expectMessage("Setting 'strSetting' is of type STRING, not of type INT");
+        strSetting.valueAsInt();
+        expectedExceptions.expectMessage("Setting 'strSetting' is of type STRING, not of type LONG");
+        strSetting.valueAsLong();
+        expectedExceptions.expectMessage("Setting 'strSetting' is of type STRING, not of type LOCAL_DATE");
+        strSetting.valueAsLocalDate();
+        expectedExceptions.expectMessage("Setting 'strSetting' is of type STRING, not of type BOOLEAN");
+        strSetting.valueAsBoolean();
+        expectedExceptions.expectMessage("Setting 'intSetting' is of type INT, not of type STRING");
+        intSetting.valueAsString();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/ee10fcfb/example/application/quickstart_wicket_restful_jdo/pom.xml
----------------------------------------------------------------------
diff --git a/example/application/quickstart_wicket_restful_jdo/pom.xml b/example/application/quickstart_wicket_restful_jdo/pom.xml
index fc79c55..0d45723 100644
--- a/example/application/quickstart_wicket_restful_jdo/pom.xml
+++ b/example/application/quickstart_wicket_restful_jdo/pom.xml
@@ -30,10 +30,10 @@
     <packaging>pom</packaging>
 
 	<properties>
-        <isis.version>1.2.0</isis.version>
-		<isis-objectstore-jdo.version>1.1.0</isis-objectstore-jdo.version>
+        <isis.version>1.3.0-SNAPSHOT</isis.version>
+		<isis-objectstore-jdo.version>1.2.0-SNAPSHOT</isis-objectstore-jdo.version>
 		<isis-viewer-wicket.version>1.3.0-SNAPSHOT</isis-viewer-wicket.version>
-		<isis-viewer-restfulobjects.version>2.0.0</isis-viewer-restfulobjects.version>
+		<isis-viewer-restfulobjects.version>2.1.0-SNAPSHOT</isis-viewer-restfulobjects.version>
 		<isis-security-shiro.version>1.1.1</isis-security-shiro.version>
 
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

http://git-wip-us.apache.org/repos/asf/isis/blob/ee10fcfb/example/application/quickstart_wicket_restful_jdo/webapp/src/main/webapp/WEB-INF/isis.properties
----------------------------------------------------------------------
diff --git a/example/application/quickstart_wicket_restful_jdo/webapp/src/main/webapp/WEB-INF/isis.properties b/example/application/quickstart_wicket_restful_jdo/webapp/src/main/webapp/WEB-INF/isis.properties
index 8d35c45..a2f4f2f 100644
--- a/example/application/quickstart_wicket_restful_jdo/webapp/src/main/webapp/WEB-INF/isis.properties
+++ b/example/application/quickstart_wicket_restful_jdo/webapp/src/main/webapp/WEB-INF/isis.properties
@@ -181,6 +181,12 @@ isis.services = objstore.jdo.todo.ToDoItemsJdo,\
                 org.apache.isis.viewer.restfulobjects.rendering.eventserializer.RestfulObjectsSpecEventSerializer,\
                 org.apache.isis.applib.services.audit.AuditingService$Stderr,\
                 org.apache.isis.applib.services.publish.PublishingService$Stderr
+                
+                # if using the JDO implementation of the settings services
+                #org.apache.isis.objectstore.jdo.applib.service.settings.ApplicationSettingsServiceJdo,\
+                #org.apache.isis.objectstore.jdo.applib.service.settings.UserSettingsServiceJdo
+                
+                # if using the JDO implementation of the publishing service (replace the $Stderr implementations, above)
                 #org.apache.isis.objectstore.jdo.applib.service.audit.AuditingServiceJdo,\
                 #org.apache.isis.objectstore.jdo.applib.service.publish.PublishingServiceJdo