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 2014/09/25 11:52:21 UTC

[2/7] ISIS-887: mothballed the core/module* modules, moved to mothballed/core/module*

http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-publishing-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/IoUtils.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-publishing-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/IoUtils.java b/mothballed/core/module-publishing-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/IoUtils.java
new file mode 100644
index 0000000..d7f1ae0
--- /dev/null
+++ b/mothballed/core/module-publishing-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/IoUtils.java
@@ -0,0 +1,126 @@
+/**
+ *  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.publish;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+import org.apache.isis.applib.FatalException;
+import org.apache.isis.applib.RecoverableException;
+import org.apache.isis.applib.NonRecoverableException;
+
+class IoUtils {
+
+    public static byte[] toUtf8ZippedBytes(String entryName, final String toZip) {
+        if(toZip == null) {
+            return null;
+        }
+        ZipOutputStream zos = null;
+        ByteArrayOutputStream baos = null;
+        try {
+            baos = new ByteArrayOutputStream();
+            zos = new ZipOutputStream(baos);
+            ZipEntry entry = new ZipEntry(entryName);
+            zos.putNextEntry(entry);
+            
+            final byte[] utf8Bytes = toZip.getBytes(Charset.forName("UTF-8"));
+            zos.write(utf8Bytes);
+            zos.flush();
+        } catch (final IOException ex) {
+            throw new FatalException(ex);
+        } finally {
+            closeSafely(zos);
+        }
+        return baos.toByteArray();
+    }
+
+    public static String fromUtf8ZippedBytes(String entryName, final byte[] toUnzip) {
+        if(toUnzip == null) {
+            return null;
+        }
+        ByteArrayInputStream bais = null;
+        ZipInputStream zis = null;
+        try {
+            bais = new ByteArrayInputStream(toUnzip);
+            zis = new ZipInputStream(bais);
+            ZipEntry entry;
+            while ((entry = zis.getNextEntry()) != null) {
+                if(!entry.getName().equals(entryName)) {
+                    zis.closeEntry();
+                    continue;
+                } 
+                final byte[] utf8Bytes = IoUtils.readBytes(zis);
+                return new String(utf8Bytes, Charset.forName("UTF-8"));
+            }
+            return null;
+        } catch(IOException ex) {
+            throw new NonRecoverableException(ex);
+        } finally {
+            IoUtils.closeSafely(zis);
+        }
+    }
+
+    static byte[] readBytes(final InputStream zis) throws IOException {
+        final byte[] buffer = new byte[2048];
+        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        int numBytes;
+        while ((numBytes = zis.read(buffer, 0, buffer.length)) != -1) {
+            baos.write(buffer, 0, numBytes);
+        }
+        baos.flush();
+        baos.close();
+        return baos.toByteArray();
+    }
+
+    static void closeSafely(ZipInputStream zis) {
+        if(zis != null) {
+            try {
+                zis.closeEntry();
+            } catch (IOException e) {
+                // ignore
+            }
+            try {
+                zis.close();
+            } catch (IOException e) {
+                // ignore
+            }
+        }
+    }
+
+    static void closeSafely(ZipOutputStream zos) {
+        if(zos != null) {
+            try {
+                zos.closeEntry();
+            } catch (IOException e) {
+                // ignore
+            }
+            try {
+                zos.close();
+            } catch (IOException e) {
+                // ignore
+            }
+        }
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-publishing-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishedEventJdo.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-publishing-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishedEventJdo.java b/mothballed/core/module-publishing-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishedEventJdo.java
new file mode 100644
index 0000000..097f64c
--- /dev/null
+++ b/mothballed/core/module-publishing-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishedEventJdo.java
@@ -0,0 +1,490 @@
+/*
+ *  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.publish;
+
+import java.util.UUID;
+import javax.jdo.annotations.IdentityType;
+import org.apache.isis.applib.DomainObjectContainer;
+import org.apache.isis.applib.Identifier;
+import org.apache.isis.applib.annotation.*;
+import org.apache.isis.applib.annotation.ActionSemantics.Of;
+import org.apache.isis.applib.services.HasTransactionId;
+import org.apache.isis.applib.services.bookmark.BookmarkService;
+import org.apache.isis.applib.services.publish.EventType;
+import org.apache.isis.applib.util.ObjectContracts;
+import org.apache.isis.applib.util.TitleBuffer;
+import org.apache.isis.objectstore.jdo.applib.service.DomainChangeJdoAbstract;
+import org.apache.isis.objectstore.jdo.applib.service.JdoColumnLength;
+import org.apache.isis.objectstore.jdo.applib.service.Util;
+
+@javax.jdo.annotations.PersistenceCapable(
+        identityType=IdentityType.APPLICATION,
+        table="IsisPublishedEvent", 
+        objectIdClass=PublishedEventJdoPK.class)
+@javax.jdo.annotations.Queries( {
+    @javax.jdo.annotations.Query(
+            name="findByStateOrderByTimestamp", language="JDOQL",  
+            value="SELECT "
+                    + "FROM org.apache.isis.objectstore.jdo.applib.service.publish.PublishedEventJdo "
+                    + "WHERE state == :state "
+                    + "ORDER BY timestamp"),
+    @javax.jdo.annotations.Query(
+            name="findByTransactionId", language="JDOQL",  
+            value="SELECT "
+                    + "FROM org.apache.isis.objectstore.jdo.applib.service.publish.PublishedEventJdo "
+                    + "WHERE transactionId == :transactionId"),
+    @javax.jdo.annotations.Query(
+            name="findByTargetAndTimestampBetween", language="JDOQL",  
+            value="SELECT "
+                    + "FROM org.apache.isis.objectstore.jdo.applib.service.publish.PublishedEventJdo "
+                    + "WHERE targetStr == :targetStr " 
+                    + "&& timestamp >= :from " 
+                    + "&& timestamp <= :to "
+                    + "ORDER BY timestamp DESC"),
+    @javax.jdo.annotations.Query(
+            name="findByTargetAndTimestampAfter", language="JDOQL",  
+            value="SELECT "
+                    + "FROM org.apache.isis.objectstore.jdo.applib.service.publish.PublishedEventJdo "
+                    + "WHERE targetStr == :targetStr " 
+                    + "&& timestamp >= :from "
+                    + "ORDER BY timestamp DESC"),
+    @javax.jdo.annotations.Query(
+            name="findByTargetAndTimestampBefore", language="JDOQL",  
+            value="SELECT "
+                    + "FROM org.apache.isis.objectstore.jdo.applib.service.publish.PublishedEventJdo "
+                    + "WHERE targetStr == :targetStr " 
+                    + "&& timestamp <= :to "
+                    + "ORDER BY timestamp DESC"),
+    @javax.jdo.annotations.Query(
+            name="findByTarget", language="JDOQL",  
+            value="SELECT "
+                    + "FROM org.apache.isis.objectstore.jdo.applib.service.publish.PublishedEventJdo "
+                    + "WHERE targetStr == :targetStr " 
+                    + "ORDER BY timestamp DESC"),
+    @javax.jdo.annotations.Query(
+            name="findByTimestampBetween", language="JDOQL",  
+            value="SELECT "
+                    + "FROM org.apache.isis.objectstore.jdo.applib.service.publish.PublishedEventJdo "
+                    + "WHERE timestamp >= :from " 
+                    + "&&    timestamp <= :to "
+                    + "ORDER BY timestamp DESC"),
+    @javax.jdo.annotations.Query(
+            name="findByTimestampAfter", language="JDOQL",  
+            value="SELECT "
+                    + "FROM org.apache.isis.objectstore.jdo.applib.service.publish.PublishedEventJdo "
+                    + "WHERE timestamp >= :from "
+                    + "ORDER BY timestamp DESC"),
+    @javax.jdo.annotations.Query(
+            name="findByTimestampBefore", language="JDOQL",  
+            value="SELECT "
+                    + "FROM org.apache.isis.objectstore.jdo.applib.service.publish.PublishedEventJdo "
+                    + "WHERE timestamp <= :to "
+                    + "ORDER BY timestamp DESC"),
+    @javax.jdo.annotations.Query(
+            name="find", language="JDOQL",  
+            value="SELECT "
+                    + "FROM org.apache.isis.objectstore.jdo.applib.service.publish.PublishedEventJdo "
+                    + "ORDER BY timestamp DESC")
+})
+@MemberGroupLayout(
+        columnSpans={6,0,6},
+        left={"Identifiers","Target"},
+        right={"Detail","State"})
+@Immutable
+@Named("Published Event")
+@ObjectType("IsisPublishedEvent")
+public class PublishedEventJdo extends DomainChangeJdoAbstract implements HasTransactionId {
+
+    public static enum State {
+        QUEUED, PROCESSED
+    }
+
+    // //////////////////////////////////////
+
+    public PublishedEventJdo() {
+        super(ChangeType.PUBLISHED_EVENT);
+    }
+
+
+    // //////////////////////////////////////
+    // Identification
+    // //////////////////////////////////////
+
+    public String title() {
+        final TitleBuffer buf = new TitleBuffer();
+        buf.append(getEventType().name()).append(" ").append(getTargetStr());
+        if(getEventType()==EventType.ACTION_INVOCATION) {
+            buf.append(" ").append(getMemberIdentifier());
+        }
+        buf.append(",").append(getState());
+        return buf.toString();
+    }
+
+
+    // //////////////////////////////////////
+    // user (property)
+    // //////////////////////////////////////
+
+    private String user;
+    
+    @javax.jdo.annotations.Column(allowsNull="false", length=50)
+    @MemberOrder(name="Identifiers", sequence = "10")
+    @Hidden(where=Where.PARENTED_TABLES)
+    public String getUser() {
+        return user;
+    }
+    
+    public void setUser(final String user) {
+        this.user = user;
+    }
+    
+
+    // //////////////////////////////////////
+    // timestamp (property)
+    // //////////////////////////////////////
+
+    private java.sql.Timestamp timestamp;
+
+    @javax.jdo.annotations.Persistent
+    @javax.jdo.annotations.Column(allowsNull="false")
+    @MemberOrder(name="Identifiers", sequence = "20")
+    @Hidden(where=Where.PARENTED_TABLES)
+    public java.sql.Timestamp getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(final java.sql.Timestamp timestamp) {
+        this.timestamp = timestamp;
+    }
+    
+
+
+    // //////////////////////////////////////
+    // transactionId
+    // //////////////////////////////////////
+
+    private UUID transactionId;
+
+    /**
+     * The unique identifier (a GUID) of the transaction in which this published event was persisted.
+     * 
+     * <p>
+     * The combination of ({@link #getTransactionId() transactionId}, {@link #getSequence() sequence}) makes up the
+     * primary key.
+     */
+    @javax.jdo.annotations.PrimaryKey
+    @javax.jdo.annotations.Column(allowsNull="false",length=JdoColumnLength.TRANSACTION_ID)
+    @MemberOrder(name="Identifiers", sequence = "30")
+    @Hidden(where=Where.PARENTED_TABLES)
+    @Override
+    public UUID getTransactionId() {
+        return transactionId;
+    }
+
+    @Override
+    public void setTransactionId(final UUID transactionId) {
+        this.transactionId = transactionId;
+    }
+
+    
+    // //////////////////////////////////////
+    // sequence
+    // //////////////////////////////////////
+
+    private int sequence;
+
+    /**
+     * The 0-based additional identifier of a published event within the given {@link #getTransactionId() transaction}.
+     * 
+     * <p>
+     * The combination of ({@link #getTransactionId() transactionId}, {@link #getSequence() sequence}) makes up the
+     * primary key.
+     */
+    @javax.jdo.annotations.PrimaryKey
+    @MemberOrder(name="Identifiers", sequence = "40")
+    public int getSequence() {
+        return sequence;
+    }
+
+    public void setSequence(final int sequence) {
+        this.sequence = sequence;
+    }
+    
+
+    // //////////////////////////////////////
+    // title
+    // //////////////////////////////////////
+
+    private String title;
+
+    /**
+     * Consists of the full oidStr (with version info etc), concatenated 
+     * (if an {@link EventType#ACTION_INVOCATION}) with the name/parms of the action.
+     * 
+     * <p>
+     * @deprecated - the oid of the target is also available (without the version info) through {@link #getTarget()}, and
+     *               the action identifier is available through {@link #getMemberIdentifier()}.
+     */
+    @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.PublishedEvent.TITLE)
+    @Hidden
+    @Deprecated
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(final String title) {
+        this.title = title;
+    }
+    
+    
+    // //////////////////////////////////////
+    // eventType (property)
+    // //////////////////////////////////////
+
+    private EventType eventType;
+
+    @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.PublishedEvent.EVENT_TYPE)
+    @MemberOrder(name="Identifiers",sequence = "50")
+    public EventType getEventType() {
+        return eventType;
+    }
+
+    public void setEventType(final EventType eventType) {
+        this.eventType = eventType;
+    }
+    
+
+    // //////////////////////////////////////
+    // targetClass (property)
+    // //////////////////////////////////////
+
+    private String targetClass;
+
+    @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.TARGET_CLASS)
+    @TypicalLength(30)
+    @MemberOrder(name="Target", sequence = "10")
+    @Named("Class")
+    public String getTargetClass() {
+        return targetClass;
+    }
+
+    public void setTargetClass(final String targetClass) {
+        this.targetClass = Util.abbreviated(targetClass, JdoColumnLength.TARGET_CLASS);
+    }
+
+
+    // //////////////////////////////////////
+    // targetAction (property)
+    // //////////////////////////////////////
+    
+    private String targetAction;
+    
+    /**
+     * Only populated for {@link EventType#ACTION_INVOCATION}
+     */
+    @javax.jdo.annotations.Column(allowsNull="true", length=JdoColumnLength.TARGET_ACTION)
+    @TypicalLength(30)
+    @MemberOrder(name="Target", sequence = "20")
+    @Named("Action")
+    public String getTargetAction() {
+        return targetAction;
+    }
+    
+    public void setTargetAction(final String targetAction) {
+        this.targetAction = Util.abbreviated(targetAction, JdoColumnLength.TARGET_ACTION);
+    }
+    
+
+    // //////////////////////////////////////
+    // target (property)
+    // openTargetObject (action)
+    // //////////////////////////////////////
+
+    
+    private String targetStr;
+    @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.BOOKMARK, name="target")
+    @MemberOrder(name="Target", sequence="30")
+    @Named("Object")
+    public String getTargetStr() {
+        return targetStr;
+    }
+
+    public void setTargetStr(final String targetStr) {
+        this.targetStr = targetStr;
+    }
+
+
+    // //////////////////////////////////////
+    // memberIdentifier (property)
+    // //////////////////////////////////////
+
+    private String memberIdentifier;
+    
+    /**
+     * Holds a string representation of the invoked action, equivalent to
+     * {@link Identifier#toClassAndNameIdentityString()}.
+     * 
+     * <p>
+     * Only populated for {@link EventType#ACTION_INVOCATION}, 
+     * returns <tt>null</tt> otherwise.
+     * 
+     * <p>
+     * This property is called 'memberIdentifier' rather than 'actionIdentifier' for
+     * consistency with other services (such as auditing and publishing) that may act on
+     * properties rather than simply just actions.
+     */
+    @javax.jdo.annotations.Column(allowsNull="true", length=JdoColumnLength.MEMBER_IDENTIFIER)
+    @TypicalLength(60)
+    @Hidden(where=Where.ALL_TABLES)
+    @MemberOrder(name="Detail",sequence = "20")
+    public String getMemberIdentifier() {
+        return memberIdentifier;
+    }
+
+    public void setMemberIdentifier(final String actionIdentifier) {
+        this.memberIdentifier = Util.abbreviated(actionIdentifier, JdoColumnLength.MEMBER_IDENTIFIER);
+    }
+
+
+
+    // //////////////////////////////////////
+    // state (property)
+    // //////////////////////////////////////
+
+    private State state;
+
+    @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.PublishedEvent.STATE)
+    @MemberOrder(name="State", sequence = "30")
+    public State getState() {
+        return state;
+    }
+
+    public void setState(final State state) {
+        this.state = state;
+    }
+    private PublishedEventJdo setStateAndReturn(State state) {
+        setState(state);
+        return this;
+    }
+    
+
+    // //////////////////////////////////////
+    // serializedFormZipped (property)
+    // serializedForm (derived property)
+    // //////////////////////////////////////
+
+    @javax.jdo.annotations.NotPersistent
+    @NotPersisted
+    @MultiLine(numberOfLines=14)
+    @Hidden(where=Where.ALL_TABLES)
+    @MemberOrder(name="Detail", sequence = "40")
+    public String getSerializedForm() {
+        byte[] zipped = getSerializedFormZipped();
+        if(zipped != null) {
+            return PublishingServiceJdo.fromZippedBytes(zipped);
+        } else {
+            return getSerializedFormClob();
+        }
+    }
+
+
+    // //////////////////////////////////////
+
+    @Deprecated
+    @javax.jdo.annotations.Column(allowsNull="true")
+    private byte[] serializedFormZipped;
+
+    @Deprecated
+    @Programmatic // ignored by Isis
+    public byte[] getSerializedFormZipped() {
+        return serializedFormZipped;
+    }
+
+    @Deprecated
+    public void setSerializedFormZipped(final byte[] serializedFormZipped) {
+        this.serializedFormZipped = serializedFormZipped;
+    }
+
+    // //////////////////////////////////////
+
+    private String serializedFormClob;
+
+    @Programmatic // ignored by Isis
+    @javax.jdo.annotations.Column(allowsNull="true", jdbcType="CLOB")
+    public String getSerializedFormClob() {
+        return serializedFormClob;
+    }
+
+    public void setSerializedFormClob(final String serializedFormClob) {
+        this.serializedFormClob = serializedFormClob;
+    }
+
+
+    // //////////////////////////////////////
+    // processed (action)
+    // reQueue   (action)
+    // delete    (action)
+    // //////////////////////////////////////
+
+ 
+    @Bulk
+    @ActionSemantics(Of.IDEMPOTENT)
+    @MemberOrder( name="State", sequence="10")
+    public PublishedEventJdo processed() {
+        return setStateAndReturn(State.PROCESSED);
+    }
+
+
+    @Bulk
+    @ActionSemantics(Of.IDEMPOTENT)
+    @MemberOrder(name="State", sequence="11")
+    public PublishedEventJdo reQueue() {
+        return setStateAndReturn(State.QUEUED);
+    }
+
+    @Bulk
+    @MemberOrder(name="State", sequence="12")
+    public void delete() {
+        container.removeIfNotAlready(this);
+    }
+    
+
+    
+    // //////////////////////////////////////
+    // toString
+    // //////////////////////////////////////
+
+    @Override
+    public String toString() {
+        return ObjectContracts.toString(this, "targetStr,timestamp,user,eventType,memberIdentifier,state");
+    }
+
+
+    // //////////////////////////////////////
+    // dependencies
+    // //////////////////////////////////////
+
+    @javax.inject.Inject
+    private BookmarkService bookmarkService;
+
+    @javax.inject.Inject
+    private DomainObjectContainer container;
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-publishing-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishedEventJdoPK.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-publishing-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishedEventJdoPK.java b/mothballed/core/module-publishing-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishedEventJdoPK.java
new file mode 100644
index 0000000..0666ed3
--- /dev/null
+++ b/mothballed/core/module-publishing-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishedEventJdoPK.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.publish;
+
+import java.io.Serializable;
+import java.util.StringTokenizer;
+import java.util.UUID;
+
+public class PublishedEventJdoPK implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private static final String SEPARATOR = "_";
+
+    public UUID transactionId;
+    public int sequence;
+
+    // //////////////////////////////////////
+
+    
+    public PublishedEventJdoPK() {
+    }
+    
+    public PublishedEventJdoPK(final String value) {
+        final StringTokenizer token = new StringTokenizer (value, SEPARATOR);
+        this.transactionId = UUID.fromString(token.nextToken());
+        this.sequence = Integer.parseInt(token.nextToken());
+    }
+
+    // //////////////////////////////////////
+
+    public UUID getTransactionId() {
+        return transactionId;
+    }
+    public void setTransactionId(UUID transactionId) {
+        this.transactionId = transactionId;
+    }
+    
+    // //////////////////////////////////////
+
+    public int getSequence() {
+        return sequence;
+    }
+    public void setSequence(int sequence) {
+        this.sequence = sequence;
+    }
+    
+    // //////////////////////////////////////
+
+    
+    
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + sequence;
+        result = prime * result + ((transactionId == null) ? 0 : transactionId.hashCode());
+        return result;
+    }
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        PublishedEventJdoPK other = (PublishedEventJdoPK) obj;
+        if (sequence != other.sequence)
+            return false;
+        if (transactionId == null) {
+            if (other.transactionId != null)
+                return false;
+        } else if (!transactionId.equals(other.transactionId))
+            return false;
+        return true;
+    }
+    
+    // //////////////////////////////////////
+
+    
+    @Override
+    public String toString() {
+        return transactionId + SEPARATOR + sequence;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-publishing-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishingServiceJdo.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-publishing-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishingServiceJdo.java b/mothballed/core/module-publishing-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishingServiceJdo.java
new file mode 100644
index 0000000..6611fb9
--- /dev/null
+++ b/mothballed/core/module-publishing-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishingServiceJdo.java
@@ -0,0 +1,124 @@
+/*
+ *  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.publish;
+
+import java.util.Map;
+import javax.annotation.PostConstruct;
+import org.apache.isis.applib.AbstractService;
+import org.apache.isis.applib.annotation.DomainService;
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.services.command.CommandContext;
+import org.apache.isis.applib.services.publish.EventMetadata;
+import org.apache.isis.applib.services.publish.EventPayload;
+import org.apache.isis.applib.services.publish.EventSerializer;
+import org.apache.isis.applib.services.publish.PublishingService;
+
+/**
+ * An implementation of {@link PublishingService} that persists events as
+ * entities into a JDO-backed database.
+ */
+@DomainService
+public class PublishingServiceJdo extends AbstractService implements PublishingService {
+
+    private static final String SERIALIZED_FORM_LOCAL_KEY = "datanucleus.PublishingService.serializedForm";
+    private final static String SERIALIZED_FORM_KEY = "isis.persistor." + SERIALIZED_FORM_LOCAL_KEY;
+
+    static enum SerializedForm {
+        CLOB,
+        @Deprecated
+        ZIPPED;
+        static SerializedForm parse(final String value) {
+            return CLOB.toString().equalsIgnoreCase(value)? CLOB: ZIPPED;
+        }
+    }
+    
+    private SerializedForm serializedForm;
+
+    @Programmatic
+    @PostConstruct
+    public void init(Map<String,String> configuration) {
+        ensureDependenciesInjected();
+        serializedForm = SerializedForm.parse(configuration.get(SERIALIZED_FORM_KEY));
+    }
+
+    
+    // //////////////////////////////////////
+    
+    private void ensureDependenciesInjected() {
+        if(this.commandContext == null) {
+            throw new IllegalStateException(this.getClassName() + " requires CommandContext service to be configured");
+        }
+        if(this.eventSerializer == null) {
+            throw new IllegalStateException(this.getClassName() + " requires EventSerializer service to be configured");
+        }
+    }
+
+    
+    @Override
+    @Programmatic
+    public void publish(final EventMetadata metadata, final EventPayload payload) {
+        final String serializedEvent = eventSerializer.serialize(metadata, payload).toString();
+        final PublishedEventJdo publishedEvent = newTransientInstance(PublishedEventJdo.class);
+
+        if(this.serializedForm == SerializedForm.ZIPPED) {
+            final byte[] zippedBytes = asZippedBytes(serializedEvent);
+            publishedEvent.setSerializedFormZipped(zippedBytes);
+        } else {
+            publishedEvent.setSerializedFormClob(serializedEvent);
+        }
+        
+        publishedEvent.setTransactionId(metadata.getTransactionId());
+        publishedEvent.setSequence(metadata.getSequence());
+        publishedEvent.setEventType(metadata.getEventType());
+        publishedEvent.setTimestamp(metadata.getJavaSqlTimestamp());
+        publishedEvent.setUser(metadata.getUser());
+        publishedEvent.setTitle(metadata.getTitle());
+        
+        publishedEvent.setTargetClass(metadata.getTargetClass());
+        publishedEvent.setTarget(metadata.getTarget());
+        publishedEvent.setTargetAction(metadata.getTargetAction());
+        publishedEvent.setMemberIdentifier(metadata.getActionIdentifier());
+        
+        persist(publishedEvent);
+    }
+
+
+    static byte[] asZippedBytes(final String serializedEvent) {
+        return IoUtils.toUtf8ZippedBytes("serializedForm", serializedEvent);
+    }
+
+
+    // //////////////////////////////////////
+
+    private EventSerializer eventSerializer;
+    
+    @Override
+    public void setEventSerializer(EventSerializer eventSerializer) {
+        this.eventSerializer = eventSerializer;
+    }
+
+    static String fromZippedBytes(byte[] zipped) {
+        return IoUtils.fromUtf8ZippedBytes("serializedForm", zipped);
+    }
+
+
+    @javax.inject.Inject
+    private CommandContext commandContext;
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-publishing-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishingServiceJdoContributions.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-publishing-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishingServiceJdoContributions.java b/mothballed/core/module-publishing-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishingServiceJdoContributions.java
new file mode 100644
index 0000000..1709f64
--- /dev/null
+++ b/mothballed/core/module-publishing-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishingServiceJdoContributions.java
@@ -0,0 +1,47 @@
+/**
+ *  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.publish;
+
+import java.util.List;
+
+import org.apache.isis.applib.AbstractFactoryAndRepository;
+import org.apache.isis.applib.annotation.ActionSemantics;
+import org.apache.isis.applib.annotation.Render;
+import org.apache.isis.applib.annotation.ActionSemantics.Of;
+import org.apache.isis.applib.annotation.NotContributed;
+import org.apache.isis.applib.annotation.NotContributed.As;
+import org.apache.isis.applib.annotation.Render.Type;
+import org.apache.isis.applib.annotation.NotInServiceMenu;
+import org.apache.isis.applib.services.HasTransactionId;
+
+
+public class PublishingServiceJdoContributions extends AbstractFactoryAndRepository {
+
+    @ActionSemantics(Of.SAFE)
+    @NotInServiceMenu
+    @NotContributed(As.ACTION)
+    @Render(Type.EAGERLY)
+    public List<PublishedEventJdo> publishedEvents(final HasTransactionId hasTransactionId) {
+        return publishedEventRepository.findByTransactionId(hasTransactionId.getTransactionId());
+    }
+    
+    // //////////////////////////////////////
+
+    @javax.inject.Inject
+    private PublishingServiceJdoRepository publishedEventRepository;
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-publishing-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishingServiceJdoRepository.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-publishing-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishingServiceJdoRepository.java b/mothballed/core/module-publishing-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishingServiceJdoRepository.java
new file mode 100644
index 0000000..636369d
--- /dev/null
+++ b/mothballed/core/module-publishing-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishingServiceJdoRepository.java
@@ -0,0 +1,156 @@
+/*
+ *  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.publish;
+
+import java.sql.Timestamp;
+import java.util.List;
+import java.util.UUID;
+import org.joda.time.LocalDate;
+import org.apache.isis.applib.AbstractFactoryAndRepository;
+import org.apache.isis.applib.annotation.DomainService;
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.query.Query;
+import org.apache.isis.applib.query.QueryDefault;
+import org.apache.isis.applib.services.bookmark.Bookmark;
+
+/**
+ * Provides supporting functionality for querying and persisting
+ * {@link org.apache.isis.objectstore.jdo.applib.service.publish.PublishedEventJdo published event} entities.
+ *
+ * <p>
+ * This supporting service with no UI and no side-effects, and is there are no other implementations of the service,
+ * thus has been annotated with {@link org.apache.isis.applib.annotation.DomainService}.  This means that there is no
+ * need to explicitly register it as a service (eg in <tt>isis.properties</tt>).
+ */
+@DomainService
+public class PublishingServiceJdoRepository extends AbstractFactoryAndRepository {
+
+    @Programmatic
+    public List<PublishedEventJdo> findQueued() {
+        return allMatches(
+                new QueryDefault<PublishedEventJdo>(PublishedEventJdo.class, 
+                        "findByStateOrderByTimestamp", 
+                        "state", PublishedEventJdo.State.QUEUED));
+    }
+
+    @Programmatic
+    public List<PublishedEventJdo> findProcessed() {
+        return allMatches(
+                new QueryDefault<PublishedEventJdo>(PublishedEventJdo.class, 
+                        "findByStateOrderByTimestamp", 
+                        "state", PublishedEventJdo.State.PROCESSED));
+    }
+
+    @Programmatic
+    public List<PublishedEventJdo> findByTransactionId(final UUID transactionId) {
+        return allMatches(
+                new QueryDefault<PublishedEventJdo>(PublishedEventJdo.class, 
+                        "findByTransactionId", 
+                        "transactionId", transactionId));
+    }
+
+    @Programmatic
+    public void purgeProcessed() {
+        // REVIEW: this is not particularly performant.
+        // much better would be to go direct to the JDO API.
+        List<PublishedEventJdo> processedEvents = findProcessed();
+        for (PublishedEventJdo publishedEvent : processedEvents) {
+            publishedEvent.delete();
+        }
+    }
+
+
+    @Programmatic
+    public List<PublishedEventJdo> findByTargetAndFromAndTo(
+            final Bookmark target, 
+            final LocalDate from, 
+            final LocalDate to) {
+        final String targetStr = target.toString();
+        final Timestamp fromTs = toTimestampStartOfDayWithOffset(from, 0);
+        final Timestamp toTs = toTimestampStartOfDayWithOffset(to, 1);
+        
+        final Query<PublishedEventJdo> query;
+        if(from != null) {
+            if(to != null) {
+                query = new QueryDefault<PublishedEventJdo>(PublishedEventJdo.class, 
+                        "findByTargetAndTimestampBetween", 
+                        "targetStr", targetStr,
+                        "from", fromTs,
+                        "to", toTs);
+            } else {
+                query = new QueryDefault<PublishedEventJdo>(PublishedEventJdo.class, 
+                        "findByTargetAndTimestampAfter", 
+                        "targetStr", targetStr,
+                        "from", fromTs);
+            }
+        } else {
+            if(to != null) {
+                query = new QueryDefault<PublishedEventJdo>(PublishedEventJdo.class, 
+                        "findByTargetAndTimestampBefore", 
+                        "targetStr", targetStr,
+                        "to", toTs);
+            } else {
+                query = new QueryDefault<PublishedEventJdo>(PublishedEventJdo.class, 
+                        "findByTarget", 
+                        "targetStr", targetStr);
+            }
+        }
+        return allMatches(query);
+    }
+
+    @Programmatic
+    public List<PublishedEventJdo> findByFromAndTo(
+            final LocalDate from, 
+            final LocalDate to) {
+        final Timestamp fromTs = toTimestampStartOfDayWithOffset(from, 0);
+        final Timestamp toTs = toTimestampStartOfDayWithOffset(to, 1);
+        
+        final Query<PublishedEventJdo> query;
+        if(from != null) {
+            if(to != null) {
+                query = new QueryDefault<PublishedEventJdo>(PublishedEventJdo.class, 
+                        "findByTimestampBetween", 
+                        "from", fromTs,
+                        "to", toTs);
+            } else {
+                query = new QueryDefault<PublishedEventJdo>(PublishedEventJdo.class, 
+                        "findByTimestampAfter", 
+                        "from", fromTs);
+            }
+        } else {
+            if(to != null) {
+                query = new QueryDefault<PublishedEventJdo>(PublishedEventJdo.class, 
+                        "findByTimestampBefore", 
+                        "to", toTs);
+            } else {
+                query = new QueryDefault<PublishedEventJdo>(PublishedEventJdo.class, 
+                        "find");
+            }
+        }
+        return allMatches(query);
+    }
+    
+    private static Timestamp toTimestampStartOfDayWithOffset(final LocalDate dt, int daysOffset) {
+        return dt!=null
+                ?new java.sql.Timestamp(dt.toDateTimeAtStartOfDay().plusDays(daysOffset).getMillis())
+                :null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-publishing-jdo/src/main/resources/images/PublishedEventJdo.png
----------------------------------------------------------------------
diff --git a/mothballed/core/module-publishing-jdo/src/main/resources/images/PublishedEventJdo.png b/mothballed/core/module-publishing-jdo/src/main/resources/images/PublishedEventJdo.png
new file mode 100644
index 0000000..cb3a325
Binary files /dev/null and b/mothballed/core/module-publishing-jdo/src/main/resources/images/PublishedEventJdo.png differ

http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-publishing-jdo/src/test/java/org/apache/isis/objectstore/jdo/applib/service/publish/IoUtilsTest.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-publishing-jdo/src/test/java/org/apache/isis/objectstore/jdo/applib/service/publish/IoUtilsTest.java b/mothballed/core/module-publishing-jdo/src/test/java/org/apache/isis/objectstore/jdo/applib/service/publish/IoUtilsTest.java
new file mode 100644
index 0000000..32cfde0
--- /dev/null
+++ b/mothballed/core/module-publishing-jdo/src/test/java/org/apache/isis/objectstore/jdo/applib/service/publish/IoUtilsTest.java
@@ -0,0 +1,36 @@
+/**
+ *  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.publish;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+public class IoUtilsTest {
+
+    @Test
+    public void roundtrip() {
+        final String str = "3784y5hrfbdgkjh3qyri f£$%$YTRGFDGER$£\"Eu098987u'!\"£%^&*IO(LUKJM)";
+        final byte[] utf8ZippedBytes = IoUtils.toUtf8ZippedBytes("serializedForm", str);
+        
+        final String str2 = IoUtils.fromUtf8ZippedBytes("serializedForm", utf8ZippedBytes);
+        
+        assertThat(str, (is(str2)));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-publishingeventserializer-ro/pom.xml
----------------------------------------------------------------------
diff --git a/mothballed/core/module-publishingeventserializer-ro/pom.xml b/mothballed/core/module-publishingeventserializer-ro/pom.xml
new file mode 100644
index 0000000..b06d9ee
--- /dev/null
+++ b/mothballed/core/module-publishingeventserializer-ro/pom.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+	<parent>
+		<groupId>org.apache.isis.core</groupId>
+		<artifactId>isis</artifactId>
+        <version>1.7.0-SNAPSHOT</version>
+	</parent>
+
+    <groupId>org.apache.isis.module</groupId>
+	<artifactId>isis-module-publishingeventserializer-ro</artifactId>
+
+	<name>Isis Module: Publishing Event Servializer (Restful Objects spec)</name>
+	<description>
+		Implementation of an event serializer (as required by the publishing 
+        service) that serialized the object as a JSON representation defined
+        by the Restful Objects spec.
+	</description>
+
+	<properties>
+        <siteBaseDir>..</siteBaseDir>
+		<relativeUrl>module-publishingeventserializer-ro/</relativeUrl>
+	</properties>
+
+    <url>http://isis.apache.org/${relativeUrl}</url>
+
+	<build>
+        <resources>
+            <resource>
+                <filtering>false</filtering>
+                <directory>src/main/resources</directory>
+            </resource>
+            <resource>
+                <filtering>false</filtering>
+                <directory>src/main/java</directory>
+                <includes>
+                    <include>**</include>
+                </includes>
+                <excludes>
+                    <exclude>**/*.java</exclude>
+                </excludes>
+            </resource>
+        </resources>
+	</build>
+
+	<dependencies>
+        <dependency>
+            <groupId>org.apache.isis.core</groupId>
+            <artifactId>isis-core-applib</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.isis.core</groupId>
+            <artifactId>isis-core-viewer-restfulobjects-rendering</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.isis.core</groupId>
+            <artifactId>isis-core-unittestsupport</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+
+    </dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-publishingeventserializer-ro/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/eventserializer/EventSerializerRendererContext.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-publishingeventserializer-ro/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/eventserializer/EventSerializerRendererContext.java b/mothballed/core/module-publishingeventserializer-ro/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/eventserializer/EventSerializerRendererContext.java
new file mode 100644
index 0000000..6d10cc2
--- /dev/null
+++ b/mothballed/core/module-publishingeventserializer-ro/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/eventserializer/EventSerializerRendererContext.java
@@ -0,0 +1,95 @@
+/*
+ *  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.viewer.restfulobjects.rendering.eventserializer;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import com.google.common.collect.Sets;
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.applib.profiles.Localization;
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.adapter.oid.Oid;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
+import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
+
+class EventSerializerRendererContext implements RendererContext {
+
+    private final String baseUrl;
+    private final Where where;
+    
+    public EventSerializerRendererContext(String baseUrl, Where where) {
+        this.baseUrl = baseUrl;
+        this.where = where;
+    }
+
+    @Override
+    public String urlFor(String url) {
+        return baseUrl + url;
+    }
+
+    @Override
+    public AuthenticationSession getAuthenticationSession() {
+        return IsisContext.getAuthenticationSession();
+    }
+
+    @Override
+    public PersistenceSession getPersistenceSession() {
+        return IsisContext.getPersistenceSession();
+    }
+
+    @Override
+    public IsisConfiguration getConfiguration() {
+        return IsisContext.getConfiguration();
+    }
+
+    @Override
+    public AdapterManager getAdapterManager() {
+        return getPersistenceSession().getAdapterManager();
+    }
+
+    @Override
+    public List<List<String>> getFollowLinks() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public Where getWhere() {
+        return where;
+    }
+
+    @Override
+    public Localization getLocalization() {
+        return IsisContext.getLocalization();
+    }
+
+    private Set<Oid> rendered = Sets.newHashSet();
+    @Override
+    public boolean canEagerlyRender(ObjectAdapter objectAdapter) {
+        final Oid oid = objectAdapter.getOid();
+        return rendered.add(oid);
+    }
+
+    
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-publishingeventserializer-ro/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/eventserializer/RestfulObjectsSpecEventSerializer.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-publishingeventserializer-ro/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/eventserializer/RestfulObjectsSpecEventSerializer.java b/mothballed/core/module-publishingeventserializer-ro/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/eventserializer/RestfulObjectsSpecEventSerializer.java
new file mode 100644
index 0000000..07c19c5
--- /dev/null
+++ b/mothballed/core/module-publishingeventserializer-ro/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/eventserializer/RestfulObjectsSpecEventSerializer.java
@@ -0,0 +1,126 @@
+/*
+ *  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.viewer.restfulobjects.rendering.eventserializer;
+
+import java.io.IOException;
+import java.util.Map;
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import org.codehaus.jackson.JsonGenerationException;
+import org.codehaus.jackson.map.JsonMappingException;
+import org.apache.isis.applib.annotation.DomainService;
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.applib.services.publish.EventMetadata;
+import org.apache.isis.applib.services.publish.EventPayload;
+import org.apache.isis.applib.services.publish.EventSerializer;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.util.JsonMapper;
+import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
+import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.DomainObjectReprRenderer;
+
+/**
+ * Serializes {@link org.apache.isis.applib.services.publish.EventMetadata event metadata} and corresponding
+ * {@link org.apache.isis.applib.services.publish.EventPayload payload} into a JSON format corresponding to the
+ * domain object representation specified by the Restful Objects spec.
+ *
+ * <p>
+ * This implementation has no UI, has no side-effects, and there are no other implementations of the service API, and
+ * so it annotated with {@link org.apache.isis.applib.annotation.DomainService}.  This class is implemented in the
+ * <tt>o.a.i.module:isis-module-publishingeventserializer-ro</tt> module.  If that module is included in the classpath,
+ * it this means that this service is automatically registered; no further configuration is required.
+ */
+@DomainService
+public class RestfulObjectsSpecEventSerializer implements EventSerializer {
+
+    private final static String BASE_URL_KEY = "isis.viewer.restfulobjects.RestfulObjectsSpecEventSerializer.baseUrl";
+    private static final String BASE_URL_DEFAULT = "http://localhost:8080/restful/";
+
+    //region > init, shutdown
+    private String baseUrl;
+
+    @Programmatic
+    @PostConstruct
+    public void init(Map<String,String> props) {
+        final String baseUrlFromConfig = props.get(BASE_URL_KEY);
+        baseUrl = baseUrlFromConfig != null? baseUrlFromConfig: BASE_URL_DEFAULT;
+    }
+
+    @Programmatic
+    @PreDestroy
+    public void shutdown() {
+    }
+    //endregion
+
+    //region > serialize (API)
+    @Programmatic
+    @Override
+    public Object serialize(EventMetadata metadata, EventPayload payload) {
+        final RendererContext rendererContext = new EventSerializerRendererContext(baseUrl, Where.OBJECT_FORMS);
+
+        final JsonRepresentation payloadRepr = asPayloadRepr(rendererContext, payload);
+        final JsonRepresentation eventRepr = asEventRepr(metadata, payloadRepr);
+
+        return jsonFor(eventRepr);
+    }
+    //endregion
+
+    //region > supporting methods
+    JsonRepresentation asEventRepr(EventMetadata metadata, final JsonRepresentation payloadRepr) {
+        final JsonRepresentation eventRepr = JsonRepresentation.newMap();
+        final JsonRepresentation metadataRepr = JsonRepresentation.newMap();
+        eventRepr.mapPut("metadata", metadataRepr);
+        metadataRepr.mapPut("id", metadata.getId());
+        metadataRepr.mapPut("transactionId", metadata.getTransactionId());
+        metadataRepr.mapPut("sequence", metadata.getSequence());
+        metadataRepr.mapPut("eventType", metadata.getEventType());
+        metadataRepr.mapPut("user", metadata.getUser());
+        metadataRepr.mapPut("timestamp", metadata.getTimestamp());
+        eventRepr.mapPut("payload", payloadRepr);
+        return eventRepr;
+    }
+
+    JsonRepresentation asPayloadRepr(final RendererContext rendererContext, EventPayload payload) {
+        final DomainObjectReprRenderer renderer = new DomainObjectReprRenderer(rendererContext, null, JsonRepresentation.newMap());
+        final ObjectAdapter objectAdapter = rendererContext.getAdapterManager().adapterFor(payload);
+        renderer.with(objectAdapter).asEventSerialization();
+        return renderer.render();
+    }
+
+    String jsonFor(final Object object) {
+        try {
+            return getJsonMapper().write(object);
+        } catch (final JsonGenerationException e) {
+            throw new RuntimeException(e);
+        } catch (final JsonMappingException e) {
+            throw new RuntimeException(e);
+        } catch (final IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private final static JsonMapper jsonMapper = JsonMapper.instance();
+
+    JsonMapper getJsonMapper() {
+        return jsonMapper;
+    }
+    //endregion
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-publishingeventserializer-ro/src/main/resources/images/PublishedEventJdo.png
----------------------------------------------------------------------
diff --git a/mothballed/core/module-publishingeventserializer-ro/src/main/resources/images/PublishedEventJdo.png b/mothballed/core/module-publishingeventserializer-ro/src/main/resources/images/PublishedEventJdo.png
new file mode 100644
index 0000000..cb3a325
Binary files /dev/null and b/mothballed/core/module-publishingeventserializer-ro/src/main/resources/images/PublishedEventJdo.png differ

http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-settings/.gitignore
----------------------------------------------------------------------
diff --git a/mothballed/core/module-settings/.gitignore b/mothballed/core/module-settings/.gitignore
new file mode 100644
index 0000000..a48e45b
--- /dev/null
+++ b/mothballed/core/module-settings/.gitignore
@@ -0,0 +1 @@
+/target-ide

http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-settings/applib/.gitignore
----------------------------------------------------------------------
diff --git a/mothballed/core/module-settings/applib/.gitignore b/mothballed/core/module-settings/applib/.gitignore
new file mode 100644
index 0000000..a48e45b
--- /dev/null
+++ b/mothballed/core/module-settings/applib/.gitignore
@@ -0,0 +1 @@
+/target-ide

http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-settings/applib/pom.xml
----------------------------------------------------------------------
diff --git a/mothballed/core/module-settings/applib/pom.xml b/mothballed/core/module-settings/applib/pom.xml
new file mode 100644
index 0000000..9f586c5
--- /dev/null
+++ b/mothballed/core/module-settings/applib/pom.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+	<parent>
+		<groupId>org.apache.isis.module</groupId>
+		<artifactId>isis-module-settings</artifactId>
+        <version>1.7.0-SNAPSHOT</version>
+	</parent>
+
+	<artifactId>isis-module-settings-applib</artifactId>
+
+	<name>Isis Module: App and User Settings applib</name>
+	<description>
+		API for the application and user settings module.
+	</description>
+
+	<properties>
+        <siteBaseDir>../..</siteBaseDir>
+		<relativeUrl>module-settings/applib/</relativeUrl>
+	</properties>
+
+    <url>http://isis.apache.org/${relativeUrl}</url>
+
+	<dependencies>
+        <dependency>
+            <groupId>org.apache.isis.core</groupId>
+            <artifactId>isis-core-applib</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.isis.core</groupId>
+            <artifactId>isis-core-unittestsupport</artifactId>
+            <scope>test</scope>
+        </dependency>
+   </dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/ApplicationSetting.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/ApplicationSetting.java b/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/ApplicationSetting.java
new file mode 100644
index 0000000..06d4ec1
--- /dev/null
+++ b/mothballed/core/module-settings/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/790e70df/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/ApplicationSettingsService.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/ApplicationSettingsService.java b/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/ApplicationSettingsService.java
new file mode 100644
index 0000000..d6ded31
--- /dev/null
+++ b/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/ApplicationSettingsService.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 java.util.List;
+
+import org.apache.isis.applib.annotation.MemberOrder;
+import org.apache.isis.applib.annotation.Named;
+
+public interface ApplicationSettingsService {
+
+    @MemberOrder(sequence="1")
+    ApplicationSetting find(@Named("Key") String key);
+
+    @MemberOrder(sequence="2")
+    List<ApplicationSetting> listAll();
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/ApplicationSettingsServiceRW.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/ApplicationSettingsServiceRW.java b/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/ApplicationSettingsServiceRW.java
new file mode 100644
index 0000000..ae680eb
--- /dev/null
+++ b/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/ApplicationSettingsServiceRW.java
@@ -0,0 +1,38 @@
+/*
+ *  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;
+
+public interface ApplicationSettingsServiceRW extends ApplicationSettingsService {
+
+    @MemberOrder(sequence="11")
+    ApplicationSetting newBoolean(String name, String description, Boolean defaultValue);
+    @MemberOrder(sequence="12")
+    ApplicationSetting newString(String name, String description, String defaultValue);
+    @MemberOrder(sequence="13")
+    ApplicationSetting newLocalDate(String name, String description, LocalDate defaultValue);
+    @MemberOrder(sequence="14")
+    ApplicationSetting newInt(String name, String description, Integer defaultValue);
+    @MemberOrder(sequence="15")
+    ApplicationSetting newLong(String name, String description, Long defaultValue);
+    
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/Setting.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/Setting.java b/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/Setting.java
new file mode 100644
index 0000000..3999d4c
--- /dev/null
+++ b/mothballed/core/module-settings/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/790e70df/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/SettingAbstract.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/SettingAbstract.java b/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/SettingAbstract.java
new file mode 100644
index 0000000..6eb39c8
--- /dev/null
+++ b/mothballed/core/module-settings/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/790e70df/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/SettingType.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/SettingType.java b/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/SettingType.java
new file mode 100644
index 0000000..a652bf3
--- /dev/null
+++ b/mothballed/core/module-settings/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/790e70df/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/UserSetting.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/UserSetting.java b/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/UserSetting.java
new file mode 100644
index 0000000..24ccf65
--- /dev/null
+++ b/mothballed/core/module-settings/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/790e70df/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/UserSettingsService.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/UserSettingsService.java b/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/UserSettingsService.java
new file mode 100644
index 0000000..f798e62
--- /dev/null
+++ b/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/UserSettingsService.java
@@ -0,0 +1,36 @@
+/*
+ *  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 java.util.List;
+
+import org.apache.isis.applib.annotation.MemberOrder;
+import org.apache.isis.applib.annotation.Named;
+
+public interface UserSettingsService {
+
+    @MemberOrder(sequence="1")
+    UserSetting find(@Named("User") String user, @Named("Key") String key);
+    
+    @MemberOrder(sequence="2")
+    List<UserSetting> listAll();
+
+    @MemberOrder(sequence="3")
+    List<UserSetting> listAllFor(@Named("User") String user);
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/UserSettingsServiceRW.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/UserSettingsServiceRW.java b/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/UserSettingsServiceRW.java
new file mode 100644
index 0000000..8b048ea
--- /dev/null
+++ b/mothballed/core/module-settings/applib/src/main/java/org/apache/isis/applib/services/settings/UserSettingsServiceRW.java
@@ -0,0 +1,38 @@
+/*
+ *  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;
+
+public interface UserSettingsServiceRW extends UserSettingsService {
+
+    @MemberOrder(sequence="11")
+    UserSetting newBoolean(String user, String name, String description, Boolean defaultValue);
+    @MemberOrder(sequence="12")
+    UserSetting newString(String user, String name, String description, String defaultValue);
+    @MemberOrder(sequence="13")
+    UserSetting newLocalDate(String user, String name, String description, LocalDate defaultValue);
+    @MemberOrder(sequence="14")
+    UserSetting newInt(String user, String name, String description, Integer defaultValue);
+    @MemberOrder(sequence="15")
+    UserSetting newLong(String user, String name, String description, Long defaultValue);
+    
+}