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/12/29 13:42:52 UTC

[2/2] isis git commit: ISIS-970: further tidy up and refinements to the new annotations and enums. First-cut (untested) implementation of @DomainObject facet factory.

ISIS-970: further tidy up and refinements to the new annotations and enums.  First-cut (untested) implementation of @DomainObject facet factory.


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

Branch: refs/heads/ISIS-970
Commit: 93a81dba2f557201043121fb1347f7262e080782
Parents: 0bdda6e
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Mon Dec 29 12:42:43 2014 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Mon Dec 29 12:42:43 2014 +0000

----------------------------------------------------------------------
 .../apache/isis/applib/annotation/Action.java   | 163 ++++++-------------
 .../isis/applib/annotation/Bookmarkable.java    |   4 +-
 .../org/apache/isis/applib/annotation/Bulk.java |  10 +-
 .../isis/applib/annotation/Collection.java      |  13 +-
 .../apache/isis/applib/annotation/Command.java  |  15 +-
 .../applib/annotation/CommandExecuteIn.java     |  61 +++++++
 .../applib/annotation/CommandPersistence.java   |  66 ++++++++
 .../isis/applib/annotation/CommandPolicy.java   |  51 ++++++
 .../apache/isis/applib/annotation/Disabled.java |  10 +-
 .../isis/applib/annotation/DomainObject.java    |  32 ++--
 .../applib/annotation/DomainObjectLayout.java   |   2 +-
 .../isis/applib/annotation/EditPolicy.java      |  45 +++++
 .../isis/applib/annotation/Immutable.java       |   4 +-
 .../apache/isis/applib/annotation/Property.java |  13 +-
 .../applib/annotation/PublishingPolicy.java     |  41 +++++
 .../object/audit/AuditableFacetAbstract.java    |   2 -
 .../AuditableFacetFromConfigurationFactory.java |  22 +--
 .../BookmarkPolicyFacetAbstract.java            |   5 +
 ...arkPolicyFacetViaBookmarkableAnnotation.java |   4 +-
 ...cyFacetViaBookmarkableAnnotationFactory.java |   2 +-
 .../domainobject/AuditObjectsConfiguration.java |  28 ++++
 ...AuditableFacetForDomainObjectAnnotation.java |  64 ++++++++
 ...oCompleteFacetForDomainObjectAnnotation.java |  54 ++++++
 .../ChoicesFacetForDomainObjectAnnotation.java  |  42 +++++
 .../domainobject/DomainObjectFactory.java       | 158 ++++++++++++++++++
 .../EditingObjectsConfiguration.java            |  23 +++
 ...ImmutableFacetForDomainObjectAnnotation.java |  83 ++++++++++
 ...ectSpecIdFacetForDomainObjectAnnotation.java |  45 +++++
 .../PublishObjectsConfiguration.java            |  24 +++
 ...hedObjectFacetForDomainObjectAnnotation.java | 100 ++++++++++++
 ...ViewModelFacetForDomainObjectAnnotation.java |  54 ++++++
 ...icyFacetForDomainObjectLayoutAnnotation.java |  42 +++++
 ...assFacetForDomainObjectLayoutAnnotation.java |  42 +++++
 ...dAsFacetForDomainObjectLayoutAnnotation.java |  42 +++++
 .../DomainObjectLayoutFactory.java              |  54 ++++++
 ...medFacetForDomainObjectLayoutAnnotation.java |  42 +++++
 ...gedFacetForDomainObjectLayoutAnnotation.java |  41 +++++
 ...ralFacetForDomainObjectLayoutAnnotation.java |  42 +++++
 ...assFacetForDomainObjectLayoutAnnotation.java |  42 -----
 ...dAsFacetForDomainObjectLayoutAnnotation.java |  42 -----
 .../layout/DomainObjectLayoutFactory.java       |  53 ------
 ...medFacetForDomainObjectLayoutAnnotation.java |  42 -----
 ...gedFacetForDomainObjectLayoutAnnotation.java |  41 -----
 ...ralFacetForDomainObjectLayoutAnnotation.java |  42 -----
 .../ObjectFacetSpecIdAnnotationFactory.java     |  46 ------
 .../ObjectSpecIdFacetAnnotationFactory.java     |  46 ++++++
 .../ViewModelFacetDeclarativeAbstract.java      | 154 ++++++++++++++++++
 .../annotation/ViewModelFacetAnnotation.java    | 123 +-------------
 .../dflt/ProgrammingModelFacetsJava5.java       |   6 +-
 .../ObjectTypeAnnotationFacetFactoryTest.java   |   6 +-
 50 files changed, 1574 insertions(+), 614 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/applib/src/main/java/org/apache/isis/applib/annotation/Action.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/Action.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/Action.java
index c498200..87a1642 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/annotation/Action.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/Action.java
@@ -89,23 +89,6 @@ public @interface Action {
 
     // //////////////////////////////////////
 
-
-    /**
-     * Indicates when an action is not invokable by the user.
-     */
-    Where disabled() default Where.NOWHERE;
-
-
-    /**
-     * If {@link #disabled()} (in any {@link org.apache.isis.applib.annotation.Where} context), then the reason to provide to the user as to why the
-     * collection cannot be edited.
-     * @return
-     */
-    String disabledReason();
-
-
-    // //////////////////////////////////////
-
     enum Semantics {
 
         /**
@@ -182,34 +165,56 @@ public @interface Action {
     // //////////////////////////////////////
 
 
-    enum BulkAppliesTo {
-        BULK_AND_REGULAR,
-        BULK_ONLY;
+    /**
+     * Whether an action can be invoked on a single object and/or on many objects in a collection.
+     */
+    enum AppliesToPolicy {
+        /**
+         * The action can only be invoked on a single object.  This is the default.
+         */
+        OBJECT_ONLY,
+        /**
+         * The action can be invoked either on a single object or on a collection of objects (each in turn).
+         *
+         * <p>
+         *     Corresponds to (the deprecated) <code>@Bulk(appliesTo=BULK_AND_REGULAR)</code> annotation.
+         * </p>
+         */
+        OBJECT_AND_COLLECTION,
+        /**
+         * The action is intended to be invoked only on a collection of objects (each in turn).
+         *
+         * <p>
+         *     Corresponds to (the deprecated) <code>@Bulk(appliesTo=BULK_ONLY)</code> annotation.
+         * </p>
+         */
+        COLLECTION_ONLY;
 
         @Deprecated
-        public static Bulk.AppliesTo from(final BulkAppliesTo bulkAppliesTo) {
-            if(bulkAppliesTo == null) return null;
-            if(bulkAppliesTo == BULK_AND_REGULAR) return Bulk.AppliesTo.BULK_AND_REGULAR;
-            if(bulkAppliesTo == BULK_ONLY) return Bulk.AppliesTo.BULK_ONLY;
+        public static Bulk.AppliesTo from(final AppliesToPolicy appliesToPolicy) {
+            if(appliesToPolicy == null) return null;
+            if(appliesToPolicy == OBJECT_AND_COLLECTION) return Bulk.AppliesTo.BULK_AND_REGULAR;
+            if(appliesToPolicy == COLLECTION_ONLY) return Bulk.AppliesTo.BULK_ONLY;
+            if(appliesToPolicy == OBJECT_ONLY) throw new IllegalArgumentException("No corresponding Bulk.AppliesTo enum for " + appliesToPolicy);
             // shouldn't happen
-            throw new IllegalArgumentException("Unrecognized appliesTo: " + bulkAppliesTo);
+            throw new IllegalArgumentException("Unrecognized appliesTo: " + appliesToPolicy);
         }
 
         @Deprecated
-        public static BulkAppliesTo from(final Bulk.AppliesTo appliesTo) {
+        public static AppliesToPolicy from(final Bulk.AppliesTo appliesTo) {
             if(appliesTo == null) return null;
-            if(appliesTo == Bulk.AppliesTo.BULK_AND_REGULAR) return BULK_AND_REGULAR;
-            if(appliesTo == Bulk.AppliesTo.BULK_ONLY) return BULK_ONLY;
+            if(appliesTo == Bulk.AppliesTo.BULK_AND_REGULAR) return OBJECT_AND_COLLECTION;
+            if(appliesTo == Bulk.AppliesTo.BULK_ONLY) return COLLECTION_ONLY;
             // shouldn't happen
             throw new IllegalArgumentException("Unrecognized appliesTo: " + appliesTo);
         }
     }
 
     /**
-     * Indicates the (entity) action should be used only against many objects in a collection.
+     * Whether an action can be invoked on a single object and/or on many objects in a collection.
      *
      * <p>
-     * Bulk actions have a number of constraints:
+     * Actions to be invoked on collection (currently) have a number of constraints:
      * <ul>
      * <li>It must take no arguments
      * <li>It cannot be hidden (any annotations or supporting methods to that effect will be
@@ -220,84 +225,17 @@ public @interface Action {
      *
      * <p>
      * Has no meaning if annotated on an action of a domain service.
+     * </p>
      */
-    BulkAppliesTo bulk() default BulkAppliesTo.BULK_AND_REGULAR;
-
+    AppliesToPolicy appliesTo() default AppliesToPolicy.OBJECT_ONLY;
 
     // //////////////////////////////////////
 
-    enum CommandExecuteIn {
-        /**
-         * Execute synchronously in the &quot;foreground&quot;, wait for the results.
-         */
-        FOREGROUND,
-        /**
-         * Execute &quot;asynchronously&quot; through the {@link org.apache.isis.applib.services.background.BackgroundCommandService}, returning (if possible) the
-         * persisted {@link org.apache.isis.applib.services.command.Command command} object as a placeholder to the
-         * result.
-         */
-        BACKGROUND;
-
-        @Deprecated
-        public static CommandExecuteIn from(final Command.ExecuteIn executeIn) {
-            if(executeIn == null) return null;
-            if(executeIn == Command.ExecuteIn.FOREGROUND) return FOREGROUND;
-            if(executeIn == Command.ExecuteIn.BACKGROUND) return BACKGROUND;
-            // shouldn't happen
-            throw new IllegalArgumentException("Unrecognized : executeIn" + executeIn);
-        }
-
-        @Deprecated
-        public static Command.ExecuteIn from(final CommandExecuteIn commandExecuteIn) {
-            if(commandExecuteIn == null) return null;
-            if(commandExecuteIn == FOREGROUND) return Command.ExecuteIn.FOREGROUND;
-            if(commandExecuteIn == BACKGROUND) return Command.ExecuteIn.BACKGROUND;
-            // shouldn't happen
-            throw new IllegalArgumentException("Unrecognized : executeIn" + commandExecuteIn);
-        }
-
-    }
-
-    enum CommandPersistence {
-        /**
-         * (If the configured {@link org.apache.isis.applib.services.command.spi.CommandService} supports it), indicates that the
-         * {@link org.apache.isis.applib.services.command.Command Command} object should be persisted.
-         */
-        PERSISTED,
-        /**
-         * (If the configured {@link org.apache.isis.applib.services.command.spi.CommandService} supports it), indicates that the
-         * {@link org.apache.isis.applib.services.command.Command Command} object should only be persisted if
-         * another service, such as the {@link org.apache.isis.applib.services.background.BackgroundCommandService}, hints that it should.
-         */
-        IF_HINTED,
-        /**
-         * (Even if the configured {@link org.apache.isis.applib.services.command.spi.CommandService} supports it), indicates that the
-         * {@link org.apache.isis.applib.services.command.Command Command} object should <i>not</i> be persisted (even if
-         * another service, such as the {@link org.apache.isis.applib.services.background.BackgroundCommandService}, hints that it should).
-         */
-        NOT_PERSISTED;
-
-        @Deprecated
-        public static CommandPersistence from(final Command.Persistence persistence) {
-            if(persistence == null) return null;
-            if(persistence == Command.Persistence.PERSISTED) return PERSISTED;
-            if(persistence == Command.Persistence.IF_HINTED) return IF_HINTED;
-            // shouldn't happen
-            throw new IllegalArgumentException("Unrecognized : persistence" + persistence);
-        }
 
-        @Deprecated
-        public static Command.Persistence from(final CommandPersistence commandPersistence) {
-            if(commandPersistence == null) return null;
-            if(commandPersistence == PERSISTED) return Command.Persistence.PERSISTED;
-            if(commandPersistence == IF_HINTED) return Command.Persistence.IF_HINTED;
-            // shouldn't happen
-            throw new IllegalArgumentException("Unrecognized : persistence" + commandPersistence);
-        }
-    }
-
-
-    boolean command() default false;
+    /**
+     * Whether the action invocation should be reified into a {@link org.apache.isis.applib.services.command.Command} object.
+     */
+    CommandPolicy command() default CommandPolicy.AS_CONFIGURED;
 
     /**
      * How the {@link org.apache.isis.applib.services.command.Command Command} object provided by the
@@ -316,12 +254,6 @@ public @interface Action {
      */
     CommandExecuteIn commandExecuteIn() default CommandExecuteIn.FOREGROUND;
 
-    /**
-     * If set to <tt>true</tt>, acts as an override to <i>disable</i> command semantics for the action when it is
-     * otherwise (eg through configuration) configured as the default.
-     */
-    boolean commandDisabled() default false;
-
 
     // //////////////////////////////////////
 
@@ -350,9 +282,18 @@ public @interface Action {
     }
 
 
-    // TODO: factor out PayloadFactory.Default so similar to interaction
-    Class<? extends PublishingPayloadFactory> publishingPayloadFactory() default PublishingPayloadFactory.class;
+    /**
+     * Whether changes to the object should be published.
+     *
+     * <p>
+     * Requires that an implementation of the {@link org.apache.isis.applib.services.publish.PublishingService} is
+     * registered with the framework.
+     * </p>
+     */
+    PublishingPolicy publishing() default PublishingPolicy.AS_CONFIGURED;
 
 
+    // TODO: factor out PayloadFactory.Default so similar to interaction
+    Class<? extends PublishingPayloadFactory> publishingPayloadFactory() default PublishingPayloadFactory.class;
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/applib/src/main/java/org/apache/isis/applib/annotation/Bookmarkable.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/Bookmarkable.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/Bookmarkable.java
index c338d76..18e2b06 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/annotation/Bookmarkable.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/Bookmarkable.java
@@ -32,7 +32,7 @@ import java.lang.annotation.Target;
  * Three {@link BookmarkPolicy policies} are defined, which control how bookmarked entities are organized.
  * These have no meaning for bookmarkable actions.
  *
- * @deprecated - see {@link DomainObjectLayout#bookmarkable()}.
+ * @deprecated - see {@link DomainObjectLayout#bookmarking()}.
  */
 @Inherited
 @Target({ ElementType.TYPE, ElementType.METHOD })
@@ -40,7 +40,7 @@ import java.lang.annotation.Target;
 public @interface Bookmarkable {
 
     /**
-     * @deprecated - see {@link DomainObjectLayout#bookmarkable()}.
+     * @deprecated - see {@link DomainObjectLayout#bookmarking()}.
      */
     @Deprecated
     BookmarkPolicy value() default BookmarkPolicy.AS_ROOT;  

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/applib/src/main/java/org/apache/isis/applib/annotation/Bulk.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/Bulk.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/Bulk.java
index 0db18f5..945ea46 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/annotation/Bulk.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/Bulk.java
@@ -26,7 +26,7 @@ import java.util.List;
 import javax.enterprise.context.RequestScoped;
 
 /**
- * @deprecated - use {@link Action#bulk()} instead.
+ * @deprecated - use {@link Action#appliesTo()} instead.
  */
 @Inherited
 @Target({ ElementType.METHOD })
@@ -35,24 +35,24 @@ import javax.enterprise.context.RequestScoped;
 public @interface Bulk {
 
     /**
-     * @deprecated - see {@link org.apache.isis.applib.annotation.Action.BulkAppliesTo}
+     * @deprecated - see {@link org.apache.isis.applib.annotation.Action.AppliesToPolicy}
      */
     @Deprecated
     public static enum AppliesTo {
         /**
-         * @deprecated - see {@link org.apache.isis.applib.annotation.Action.BulkAppliesTo#BULK_AND_REGULAR}
+         * @deprecated - see {@link org.apache.isis.applib.annotation.Action.AppliesToPolicy#OBJECT_AND_COLLECTION}
          */
         @Deprecated
         BULK_AND_REGULAR,
         /**
-         * @deprecated - see {@link org.apache.isis.applib.annotation.Action.BulkAppliesTo#BULK_ONLY}
+         * @deprecated - see {@link org.apache.isis.applib.annotation.Action.AppliesToPolicy#COLLECTION_ONLY}
          */
         @Deprecated
         BULK_ONLY
     }
 
     /**
-     * @deprecated - see {@link Action#bulk()}.
+     * @deprecated - see {@link Action#appliesTo()}.
      */
     @Deprecated
     AppliesTo value() default AppliesTo.BULK_AND_REGULAR;

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/applib/src/main/java/org/apache/isis/applib/annotation/Collection.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/Collection.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/Collection.java
index 75d2ecc..3afe14b 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/annotation/Collection.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/Collection.java
@@ -73,20 +73,19 @@ public @interface Collection {
     // //////////////////////////////////////
 
     /**
-     * Indicates when the collection is not editable by the user.
+     * Whether the properties of this domain object can be edited, or collections of this object be added to/removed from.
      *
      * <p>
-     * Note that if the owning domain object is {@link DomainObject#notEditable()}, then that will take precedence.
+     *     Note that non-editable objects can nevertheless have actions invoked upon them.
      * </p>
      */
-    Where disabled() default Where.NOWHERE;
+    EditPolicy editing() default EditPolicy.AS_CONFIGURED;
 
     /**
-     * If {@link #disabled()} (in any {@link Where} context), then the reason to provide to the user as to why the
-     * collection cannot be edited.
-     * @return
+     * If {@link #editing()} is set to {@link EditPolicy#DISABLED},
+     * then the reason to provide to the user as to why this property cannot be edited.
      */
-    String disabledReason();
+    String editingDisabledReason();
 
 
     // //////////////////////////////////////

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/applib/src/main/java/org/apache/isis/applib/annotation/Command.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/Command.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/Command.java
index 26da941..4cb8ce5 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/annotation/Command.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/Command.java
@@ -24,7 +24,6 @@ import java.lang.annotation.Inherited;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
-import org.apache.isis.applib.services.background.BackgroundCommandService;
 
 /**
  * @deprecated - use {@link Action#command()} instead
@@ -36,22 +35,22 @@ import org.apache.isis.applib.services.background.BackgroundCommandService;
 public @interface Command {
 
     /**
-     * @deprecated - see {@link org.apache.isis.applib.annotation.Action.CommandPersistence}
+     * @deprecated - see {@link CommandPersistence}
      */
     @Deprecated
     public static enum Persistence {
         /**
-         * @deprecated - see {@link org.apache.isis.applib.annotation.Action.CommandPersistence#PERSISTED}
+         * @deprecated - see {@link CommandPersistence#PERSISTED}
          */
         @Deprecated
         PERSISTED,
         /**
-         * @deprecated - see {@link org.apache.isis.applib.annotation.Action.CommandPersistence#IF_HINTED}
+         * @deprecated - see {@link CommandPersistence#IF_HINTED}
          */
         @Deprecated
         IF_HINTED,
         /**
-         * @deprecated - see {@link org.apache.isis.applib.annotation.Action.CommandPersistence#NOT_PERSISTED}
+         * @deprecated - see {@link CommandPersistence#NOT_PERSISTED}
          */
         @Deprecated
         NOT_PERSISTED
@@ -68,17 +67,17 @@ public @interface Command {
 
 
     /**
-     * @deprecated - use {@link org.apache.isis.applib.annotation.Action.CommandExecuteIn}
+     * @deprecated - use {@link CommandExecuteIn}
      */
     @Deprecated
     public static enum ExecuteIn {
         /**
-         * @deprecated - use {@link org.apache.isis.applib.annotation.Action.CommandExecuteIn#FOREGROUND}
+         * @deprecated - use {@link CommandExecuteIn#FOREGROUND}
          */
         @Deprecated
         FOREGROUND,
         /**
-         * @deprecated - use {@link org.apache.isis.applib.annotation.Action.CommandExecuteIn#BACKGROUND}
+         * @deprecated - use {@link CommandExecuteIn#BACKGROUND}
          */
         @Deprecated
         BACKGROUND

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/applib/src/main/java/org/apache/isis/applib/annotation/CommandExecuteIn.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/CommandExecuteIn.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/CommandExecuteIn.java
new file mode 100644
index 0000000..de793f5
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/CommandExecuteIn.java
@@ -0,0 +1,61 @@
+/*
+ *  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.annotation;
+
+/**
+ * Whether a command should be executed immediately and synchronously in the foreground or rather should only be
+ * persisted (such that it can be executed asynchronously in the background by some other mechanism).
+ *
+ * <p>
+ *     Note: this enum is <i>not</i> an inner class of the {@link org.apache.isis.applib.annotation.Action} annotation
+ *     because in the future we may also support commands for {@link org.apache.isis.applib.annotation.Property} and
+ *     {@link org.apache.isis.applib.annotation.Collection}.
+ * </p>
+ */
+public enum CommandExecuteIn {
+    /**
+     * Execute synchronously in the &quot;foreground&quot;, wait for the results.
+     */
+    FOREGROUND,
+    /**
+     * Execute &quot;asynchronously&quot; through the {@link org.apache.isis.applib.services.background.BackgroundCommandService}, returning (if possible) the
+     * persisted {@link org.apache.isis.applib.services.command.Command command} object as a placeholder to the
+     * result.
+     */
+    BACKGROUND;
+
+    @Deprecated
+    public static CommandExecuteIn from(final Command.ExecuteIn executeIn) {
+        if(executeIn == null) return null;
+        if(executeIn == Command.ExecuteIn.FOREGROUND) return FOREGROUND;
+        if(executeIn == Command.ExecuteIn.BACKGROUND) return BACKGROUND;
+        // shouldn't happen
+        throw new IllegalArgumentException("Unrecognized : executeIn" + executeIn);
+    }
+
+    @Deprecated
+    public static Command.ExecuteIn from(final CommandExecuteIn commandExecuteIn) {
+        if(commandExecuteIn == null) return null;
+        if(commandExecuteIn == FOREGROUND) return Command.ExecuteIn.FOREGROUND;
+        if(commandExecuteIn == BACKGROUND) return Command.ExecuteIn.BACKGROUND;
+        // shouldn't happen
+        throw new IllegalArgumentException("Unrecognized : executeIn" + commandExecuteIn);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/applib/src/main/java/org/apache/isis/applib/annotation/CommandPersistence.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/CommandPersistence.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/CommandPersistence.java
new file mode 100644
index 0000000..a09923c
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/CommandPersistence.java
@@ -0,0 +1,66 @@
+/*
+ *  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.annotation;
+
+/**
+ * Whether the command should be persisted.
+ *
+ * <p>
+ *     Note: this enum is <i>not</i> an inner class of the {@link org.apache.isis.applib.annotation.Action} annotation
+ *     because in the future we may also support commands for {@link org.apache.isis.applib.annotation.Property} and
+ *     {@link org.apache.isis.applib.annotation.Collection}.
+ * </p>
+ */
+public enum CommandPersistence {
+    /**
+     * (If the configured {@link org.apache.isis.applib.services.command.spi.CommandService} supports it), indicates that the
+     * {@link org.apache.isis.applib.services.command.Command Command} object should be persisted.
+     */
+    PERSISTED,
+    /**
+     * (If the configured {@link org.apache.isis.applib.services.command.spi.CommandService} supports it), indicates that the
+     * {@link org.apache.isis.applib.services.command.Command Command} object should only be persisted if
+     * another service, such as the {@link org.apache.isis.applib.services.background.BackgroundCommandService}, hints that it should.
+     */
+    IF_HINTED,
+    /**
+     * (Even if the configured {@link org.apache.isis.applib.services.command.spi.CommandService} supports it), indicates that the
+     * {@link org.apache.isis.applib.services.command.Command Command} object should <i>not</i> be persisted (even if
+     * another service, such as the {@link org.apache.isis.applib.services.background.BackgroundCommandService}, hints that it should).
+     */
+    NOT_PERSISTED;
+
+    @Deprecated
+    public static CommandPersistence from(final Command.Persistence persistence) {
+        if(persistence == null) return null;
+        if(persistence == Command.Persistence.PERSISTED) return PERSISTED;
+        if(persistence == Command.Persistence.IF_HINTED) return IF_HINTED;
+        // shouldn't happen
+        throw new IllegalArgumentException("Unrecognized : persistence" + persistence);
+    }
+
+    @Deprecated
+    public static Command.Persistence from(final CommandPersistence commandPersistence) {
+        if(commandPersistence == null) return null;
+        if(commandPersistence == PERSISTED) return Command.Persistence.PERSISTED;
+        if(commandPersistence == IF_HINTED) return Command.Persistence.IF_HINTED;
+        // shouldn't happen
+        throw new IllegalArgumentException("Unrecognized : persistence" + commandPersistence);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/applib/src/main/java/org/apache/isis/applib/annotation/CommandPolicy.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/CommandPolicy.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/CommandPolicy.java
new file mode 100644
index 0000000..9edf998
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/CommandPolicy.java
@@ -0,0 +1,51 @@
+/*
+ *  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.annotation;
+
+/**
+ * The available policies as to whether action invocations are reified into commands.
+ *
+ * <p>
+ *     Note: this enum is <i>not</i> an inner class of the {@link org.apache.isis.applib.annotation.Action} annotation
+ *     because in the future we may also support commands for {@link org.apache.isis.applib.annotation.Property} and
+ *     {@link org.apache.isis.applib.annotation.Collection}.
+ * </p>
+ */
+public enum CommandPolicy {
+    /**
+     * Whether the action should be handled as a command is per the default editing policy configured in <tt>isis.properties</tt>.
+     *
+     * <p>
+     *     If no command policy is configured, then the action is <i>not</i> treated as a command.
+     * </p>
+     */
+    AS_CONFIGURED,
+    /**
+     * Audit changes to this object.
+     */
+    ENABLED,
+    /**
+     * Do not allow the properties to be edited, or the collections to be added to/removed from.
+     *
+     * <p>
+     *     Corresponds to the {@link Immutable} annotation).
+     * </p>
+     */
+    DISABLED
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/applib/src/main/java/org/apache/isis/applib/annotation/Disabled.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/Disabled.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/Disabled.java
index 33a01e0..531d81b 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/annotation/Disabled.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/Disabled.java
@@ -26,7 +26,7 @@ import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
 /**
- * @deprecated - see {@link Property#disabled()}, {@link Collection#disabled()} and {@link Action#disabled()}.
+ * @deprecated - see {@link Property#editing()} and {@link Collection#editing()}.
  */
 @Inherited
 @Target({ ElementType.METHOD })
@@ -35,18 +35,20 @@ import java.lang.annotation.Target;
 public @interface Disabled {
 
     /**
-     * @deprecated.  There is no corresponding attribute in {@link org.apache.isis.applib.annotation.Property}, {@link org.apache.isis.applib.annotation.Collection} and {@link org.apache.isis.applib.annotation.Action}, if the
-     * corresponding <code>disabled()</code> attribute is set then the feature is assumed to be disabled ALWAYS.
+     * @deprecated.  There is no corresponding attribute in {@link org.apache.isis.applib.annotation.Property}, {@link org.apache.isis.applib.annotation.Collection}; the feature is assumed to be disabled ALWAYS.
      */
     @Deprecated
     When when() default When.ALWAYS;
 
     /**
-     * @deprecated - see {@link Property#disabled()}, {@link Collection#disabled()} and {@link Action#disabled()}.
+     * @deprecated - see {@link Property#editing()} and {@link Collection#editing()}.
      */
     @Deprecated
     Where where() default Where.ANYWHERE;
 
+    /**
+     * @deprecated - see {@link Property#editingDisabledReason()} and {@link Collection#editingDisabledReason()}.
+     */
     @Deprecated
     String reason() default "";
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/applib/src/main/java/org/apache/isis/applib/annotation/DomainObject.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/DomainObject.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/DomainObject.java
index d15ba81..0140a10 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/annotation/DomainObject.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/DomainObject.java
@@ -16,7 +16,6 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-
 package org.apache.isis.applib.annotation;
 
 import java.lang.annotation.ElementType;
@@ -34,6 +33,9 @@ import org.apache.isis.applib.services.publish.EventPayload;
 @Retention(RetentionPolicy.RUNTIME)
 public @interface DomainObject {
 
+    /**
+     * The available policies for auditing changes to the properties of the object.
+     */
     public enum AuditingPolicy {
         /**
          * The auditing of the object should be as per the default auditing policy configured in <tt>isis.properties</tt>.
@@ -101,7 +103,7 @@ public @interface DomainObject {
          * Adapter to subclass if have an existing {@link org.apache.isis.applib.annotation.PublishedObject.PayloadFactory}.
          */
         @Deprecated
-        public abstract class Adapter implements PublishingPayloadFactory {
+        public static class Adapter implements PublishingPayloadFactory {
 
             private final PublishedObject.PayloadFactory payloadFactory;
 
@@ -113,9 +115,23 @@ public @interface DomainObject {
             public EventPayload payloadFor(Object changedObject, PublishingChangeKind publishingChangeKind) {
                 return payloadFactory.payloadFor(changedObject, PublishingChangeKind.from(publishingChangeKind));
             }
+
+            public PublishedObject.PayloadFactory getPayloadFactory() {
+                return payloadFactory;
+            }
         }
     }
 
+    /**
+     * Whether changes to the object should be published.
+     *
+     * <p>
+     * Requires that an implementation of the {@link org.apache.isis.applib.services.publish.PublishingService} is
+     * registered with the framework.
+     * </p>
+     */
+    PublishingPolicy publishing() default PublishingPolicy.AS_CONFIGURED;
+
     // TODO: factor out PayloadFactory.Default so similar to interaction
     Class<? extends PublishingPayloadFactory> publishingPayloadFactory() default PublishingPayloadFactory.class;
 
@@ -164,19 +180,15 @@ public @interface DomainObject {
      * <p>
      *     Note that non-editable objects can nevertheless have actions invoked upon them.
      * </p>
-     *
-     * <p>
-     *     Corresponds to the {@link org.apache.isis.applib.annotation.Immutable} annotation).
-     * </p>
      */
-    boolean notEditable() default false;
+    EditPolicy editing() default EditPolicy.AS_CONFIGURED;
 
 
     /**
-     * If {@link #notEditable()}, then the reason to provide to the user as to why the object's properties cannot be
-     * edited.
+     * If {@link #editing()} is set to {@link EditPolicy#DISABLED},
+     * then the reason to provide to the user as to why the object's properties cannot be edited/collections modified.
      */
-    String notEditableReason();
+    String editingDisabledReason();
 
 
     // //////////////////////////////////////

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/applib/src/main/java/org/apache/isis/applib/annotation/DomainObjectLayout.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/DomainObjectLayout.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/DomainObjectLayout.java
index 8fd1a1d..bfa561f 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/annotation/DomainObjectLayout.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/DomainObjectLayout.java
@@ -84,6 +84,6 @@ public @interface DomainObjectLayout {
     /**
      * Whether (and how) this domain object can be bookmarked in the UI.
      */
-    BookmarkPolicy bookmarkable() default BookmarkPolicy.AS_ROOT;
+    BookmarkPolicy bookmarking() default BookmarkPolicy.NEVER;
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/applib/src/main/java/org/apache/isis/applib/annotation/EditPolicy.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/EditPolicy.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/EditPolicy.java
new file mode 100644
index 0000000..23fe17c
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/EditPolicy.java
@@ -0,0 +1,45 @@
+/*
+ *  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.annotation;
+
+/**
+ * The available policies for editing properties and collections.
+ */
+public enum EditPolicy {
+    /**
+     * The editing of the object should be as per the default editing policy configured in <tt>isis.properties</tt>.
+     *
+     * <p>
+     *     If no editing policy is configured, then the editing is enabled.
+     * </p>
+     */
+    AS_CONFIGURED,
+    /**
+     * Audit changes to this object.
+     */
+    ENABLED,
+    /**
+     * Do not allow the properties to be edited, or the collections to be added to/removed from.
+     *
+     * <p>
+     *     Corresponds to the {@link Immutable} annotation).
+     * </p>
+     */
+    DISABLED
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/applib/src/main/java/org/apache/isis/applib/annotation/Immutable.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/Immutable.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/Immutable.java
index a95303d..831aa34 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/annotation/Immutable.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/Immutable.java
@@ -26,7 +26,7 @@ import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
 /**
- * @deprecated - use {@link DomainObject#notEditable()} instead.
+ * @deprecated - use {@link DomainObject#editing()} instead.
  */
 @Inherited
 @Target({ ElementType.TYPE })
@@ -35,7 +35,7 @@ import java.lang.annotation.Target;
 public @interface Immutable {
 
     /**
-     * @deprecated - see {@link DomainObject#notEditable()}.  <code>true</code> corresponds to {@link When#ALWAYS}, <code>false</code> corresponds to {@link org.apache.isis.applib.annotation.When#NEVER}.  The other values for the
+     * @deprecated - see {@link DomainObject#editing()}.  <code>true</code> corresponds to {@link When#ALWAYS}, <code>false</code> corresponds to {@link org.apache.isis.applib.annotation.When#NEVER}.  The other values for the
      * {@link org.apache.isis.applib.annotation.When} are not (ie no longer) supported.
      */
     @Deprecated

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/applib/src/main/java/org/apache/isis/applib/annotation/Property.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/Property.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/Property.java
index c47e5fe..d1f9165 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/annotation/Property.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/Property.java
@@ -74,20 +74,19 @@ public @interface Property {
     // //////////////////////////////////////
 
     /**
-     * Indicates when the property is not editable by the user.
+     * Whether the properties of this domain object can be edited, or collections of this object be added to/removed from.
      *
      * <p>
-     * Note that if the owning domain object is {@link DomainObject#notEditable()}, then that will take precedence.
+     *     Note that non-editable objects can nevertheless have actions invoked upon them.
      * </p>
      */
-    Where disabled() default Where.NOWHERE;
+    EditPolicy editing() default EditPolicy.AS_CONFIGURED;
 
     /**
-     * If {@link #disabled()} (in any {@link org.apache.isis.applib.annotation.Where} context), then the reason
-     * to provide to the user as to why the property cannot be edited.
-     * @return
+     * If {@link #editing()} is set to {@link EditPolicy#DISABLED},
+     * then the reason to provide to the user as to why this property cannot be edited.
      */
-    String disabledReason();
+    String editingDisabledReason();
 
 
     // //////////////////////////////////////

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/applib/src/main/java/org/apache/isis/applib/annotation/PublishingPolicy.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/PublishingPolicy.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/PublishingPolicy.java
new file mode 100644
index 0000000..35704a8
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/PublishingPolicy.java
@@ -0,0 +1,41 @@
+/*
+ *  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.annotation;
+
+/**
+ * The available policies for publishing changes to the properties of the object.
+ */
+public enum PublishingPolicy {
+    /**
+     * The publishing of the object should be as per the default publishing policy configured in <tt>isis.properties</tt>.
+     *
+     * <p>
+     *     If no publishing policy is configured, then the publishing is disabled.
+     * </p>
+     */
+    AS_CONFIGURED,
+    /**
+     * Publish changes to this object.
+     */
+    ENABLED,
+    /**
+     * Do not publish changes to this object (even if otherwise configured to enable publishing).
+     */
+    DISABLED
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/audit/AuditableFacetAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/audit/AuditableFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/audit/AuditableFacetAbstract.java
index 73343f2..0ec627a 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/audit/AuditableFacetAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/audit/AuditableFacetAbstract.java
@@ -27,8 +27,6 @@ import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 public abstract class AuditableFacetAbstract extends FacetAbstract implements
         AuditableFacet {
 
-
-
     public static Class<? extends Facet> type() {
         return AuditableFacet.class;
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/audit/configuration/AuditableFacetFromConfigurationFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/audit/configuration/AuditableFacetFromConfigurationFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/audit/configuration/AuditableFacetFromConfigurationFactory.java
index 1f49d8d..11e754c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/audit/configuration/AuditableFacetFromConfigurationFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/audit/configuration/AuditableFacetFromConfigurationFactory.java
@@ -27,36 +27,22 @@ import org.apache.isis.core.metamodel.facetapi.FacetUtil;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
 import org.apache.isis.core.metamodel.facets.object.audit.AuditableFacet;
+import org.apache.isis.core.metamodel.facets.object.domainobject.AuditObjectsConfiguration;
 
 
 public class AuditableFacetFromConfigurationFactory extends FacetFactoryAbstract implements IsisConfigurationAware {
 
-    private static final String AUDIT_OBJECTS_KEY = "isis.services.audit.objects";
-
     private IsisConfiguration configuration;
 
-    private static enum ObjectCategorization {
-        ALL,
-        NONE;
-        public static ObjectCategorization parse(final String value) {
-            if ("all".equalsIgnoreCase(value)) {
-                return ALL;
-            } else {
-                return NONE;
-            }
-        }
-    }
-    
-
     public AuditableFacetFromConfigurationFactory() {
         super(FeatureType.OBJECTS_ONLY);
     }
 
     @Override
     public void process(ProcessClassContext processClassContext) {
-        final String configuredValue = configuration.getString(AUDIT_OBJECTS_KEY);
-        final ObjectCategorization categorization = ObjectCategorization.parse(configuredValue);
-        if(categorization == ObjectCategorization.NONE) {
+
+        final AuditObjectsConfiguration categorization = AuditObjectsConfiguration.parse(configuration);
+        if(categorization == AuditObjectsConfiguration.NONE) {
             return;
         }
         final Class<?> cls = processClassContext.getCls();

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/bookmarkpolicy/BookmarkPolicyFacetAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/bookmarkpolicy/BookmarkPolicyFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/bookmarkpolicy/BookmarkPolicyFacetAbstract.java
index 3a5af44..73b84a8 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/bookmarkpolicy/BookmarkPolicyFacetAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/bookmarkpolicy/BookmarkPolicyFacetAbstract.java
@@ -35,7 +35,12 @@ public abstract class BookmarkPolicyFacetAbstract extends FacetAbstract implemen
 
     private final BookmarkPolicy bookmarkPolicy;
 
+    @Deprecated
     public BookmarkPolicyFacetAbstract(FacetHolder facetHolder, BookmarkPolicy bookmarkPolicy) {
+        this(bookmarkPolicy, facetHolder);
+    }
+
+    public BookmarkPolicyFacetAbstract(BookmarkPolicy bookmarkPolicy, FacetHolder facetHolder) {
         super(BookmarkPolicyFacetAbstract.type(), facetHolder, Derivation.NOT_DERIVED);
         this.bookmarkPolicy = bookmarkPolicy;
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/bookmarkpolicy/bookmarkable/BookmarkPolicyFacetViaBookmarkableAnnotation.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/bookmarkpolicy/bookmarkable/BookmarkPolicyFacetViaBookmarkableAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/bookmarkpolicy/bookmarkable/BookmarkPolicyFacetViaBookmarkableAnnotation.java
index a82430e..74461d6 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/bookmarkpolicy/bookmarkable/BookmarkPolicyFacetViaBookmarkableAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/bookmarkpolicy/bookmarkable/BookmarkPolicyFacetViaBookmarkableAnnotation.java
@@ -25,8 +25,8 @@ import org.apache.isis.core.metamodel.facets.object.bookmarkpolicy.BookmarkPolic
 
 public class BookmarkPolicyFacetViaBookmarkableAnnotation extends BookmarkPolicyFacetAbstract {
 
-    public BookmarkPolicyFacetViaBookmarkableAnnotation(FacetHolder facetHolder, BookmarkPolicy bookmarkPolicy) {
-        super(facetHolder, bookmarkPolicy);
+    public BookmarkPolicyFacetViaBookmarkableAnnotation(BookmarkPolicy bookmarkPolicy, FacetHolder facetHolder) {
+        super(bookmarkPolicy, facetHolder);
     }
 
 

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/bookmarkpolicy/bookmarkable/BookmarkPolicyFacetViaBookmarkableAnnotationFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/bookmarkpolicy/bookmarkable/BookmarkPolicyFacetViaBookmarkableAnnotationFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/bookmarkpolicy/bookmarkable/BookmarkPolicyFacetViaBookmarkableAnnotationFactory.java
index 5185332..f28e94a 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/bookmarkpolicy/bookmarkable/BookmarkPolicyFacetViaBookmarkableAnnotationFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/bookmarkpolicy/bookmarkable/BookmarkPolicyFacetViaBookmarkableAnnotationFactory.java
@@ -60,7 +60,7 @@ public class BookmarkPolicyFacetViaBookmarkableAnnotationFactory extends FacetFa
     }
 
     private BookmarkPolicyFacet create(final Bookmarkable annotation, final FacetHolder holder) {
-        return annotation == null ? new BookmarkPolicyFacetFallback(holder) : new BookmarkPolicyFacetViaBookmarkableAnnotation(holder, annotation.value());
+        return annotation == null ? new BookmarkPolicyFacetFallback(holder) : new BookmarkPolicyFacetViaBookmarkableAnnotation(annotation.value(), holder);
     }
 
 

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/AuditObjectsConfiguration.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/AuditObjectsConfiguration.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/AuditObjectsConfiguration.java
new file mode 100644
index 0000000..cbcac23
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/AuditObjectsConfiguration.java
@@ -0,0 +1,28 @@
+package org.apache.isis.core.metamodel.facets.object.domainobject;
+
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.metamodel.facets.object.audit.AuditableFacetAbstract;
+
+public enum AuditObjectsConfiguration {
+    ALL,
+    NONE;
+
+    private static final String AUDIT_OBJECTS_KEY = "isis.services.audit.objects";
+
+    public static AuditObjectsConfiguration parse(IsisConfiguration configuration) {
+        final String configuredValue = configuration.getString(AUDIT_OBJECTS_KEY);
+        return AuditObjectsConfiguration.parse(configuredValue);
+    }
+
+    private static AuditObjectsConfiguration parse(final String value) {
+        if ("all".equalsIgnoreCase(value)) {
+            return ALL;
+        } else {
+            return NONE;
+        }
+    }
+
+    public AuditableFacetAbstract.Enablement asEnablement() {
+        return this == ALL? AuditableFacetAbstract.Enablement.ENABLED: AuditableFacetAbstract.Enablement.DISABLED;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/AuditableFacetForDomainObjectAnnotation.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/AuditableFacetForDomainObjectAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/AuditableFacetForDomainObjectAnnotation.java
new file mode 100644
index 0000000..c0ab0a1
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/AuditableFacetForDomainObjectAnnotation.java
@@ -0,0 +1,64 @@
+/*
+ *  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.core.metamodel.facets.object.domainobject;
+
+
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.object.audit.AuditableFacet;
+import org.apache.isis.core.metamodel.facets.object.audit.AuditableFacetAbstract;
+
+
+public class AuditableFacetForDomainObjectAnnotation extends AuditableFacetAbstract {
+
+    public static AuditableFacet create(
+            final DomainObject domainObject,
+            final IsisConfiguration configuration,
+            final FacetHolder holder) {
+
+        final DomainObject.AuditingPolicy auditingPolicy = domainObject.auditing();
+        switch (auditingPolicy) {
+            case AS_CONFIGURED:
+
+                //
+                // this rule also implemented in AuditableFacetFromConfigurationFactory
+                // don't overwrite if already explicitly specified.
+                //
+                if(holder.containsDoOpFacet(AuditableFacet.class)) {
+                    // do not replace
+                    return null;
+                }
+
+                final AuditObjectsConfiguration setting = AuditObjectsConfiguration.parse(configuration);
+                return setting.asEnablement() == Enablement.ENABLED
+                        ? new AuditableFacetForDomainObjectAnnotation(Enablement.ENABLED, holder)
+                        : null;
+            case DISABLED:
+                return null;
+            case ENABLED:
+                return new AuditableFacetForDomainObjectAnnotation(Enablement.ENABLED, holder);
+        }
+        return null;
+    }
+
+    private AuditableFacetForDomainObjectAnnotation(Enablement enablement, FacetHolder holder) {
+        super(holder, enablement);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/AutoCompleteFacetForDomainObjectAnnotation.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/AutoCompleteFacetForDomainObjectAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/AutoCompleteFacetForDomainObjectAnnotation.java
new file mode 100644
index 0000000..cd45b62
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/AutoCompleteFacetForDomainObjectAnnotation.java
@@ -0,0 +1,54 @@
+/*
+ *  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.core.metamodel.facets.object.domainobject;
+
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.object.autocomplete.AutoCompleteFacet;
+import org.apache.isis.core.metamodel.facets.object.autocomplete.AutoCompleteFacetAbstract;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjector;
+import org.apache.isis.core.metamodel.spec.SpecificationLoader;
+
+public class AutoCompleteFacetForDomainObjectAnnotation extends AutoCompleteFacetAbstract {
+
+    public static AutoCompleteFacet create(
+            final DomainObject domainObject,
+            final SpecificationLoader specificationLoader,
+            final AdapterManager adapterManager,
+            final ServicesInjector servicesInjector,
+            final FacetHolder holder) {
+
+        final Class<?> autoCompleteRepository = domainObject.autoCompleteRepository();
+        if(autoCompleteRepository == null) {
+            return null;
+        }
+        final String autoCompleteAction = domainObject.autoCompleteAction();
+        return new AutoCompleteFacetForDomainObjectAnnotation(holder, autoCompleteRepository, autoCompleteAction, specificationLoader, adapterManager, servicesInjector);
+    }
+
+    private AutoCompleteFacetForDomainObjectAnnotation(FacetHolder holder, Class<?> repositoryClass, String actionName, SpecificationLoader specificationLoader, AdapterManager adapterManager, ServicesInjector servicesInjector) {
+        super(holder, repositoryClass, actionName, specificationLoader, adapterManager, servicesInjector);
+    }
+
+
+
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/ChoicesFacetForDomainObjectAnnotation.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/ChoicesFacetForDomainObjectAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/ChoicesFacetForDomainObjectAnnotation.java
new file mode 100644
index 0000000..74dfa00
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/ChoicesFacetForDomainObjectAnnotation.java
@@ -0,0 +1,42 @@
+/*
+ *  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.core.metamodel.facets.object.domainobject;
+
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.core.metamodel.adapter.QuerySubmitter;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.object.choices.ChoicesFacetFromBoundedAbstract;
+
+public class ChoicesFacetForDomainObjectAnnotation extends ChoicesFacetFromBoundedAbstract {
+
+    public static Facet create(
+            final DomainObject domainObject,
+            final QuerySubmitter querySubmitter,
+            final FacetHolder facetHolder) {
+        final boolean bounded = domainObject.bounded();
+        return bounded ? new ChoicesFacetForDomainObjectAnnotation(facetHolder, querySubmitter): null;
+    }
+
+    private ChoicesFacetForDomainObjectAnnotation(final FacetHolder holder, QuerySubmitter querySubmitter) {
+        super(holder, querySubmitter);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectFactory.java
new file mode 100644
index 0000000..dce89b7
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectFactory.java
@@ -0,0 +1,158 @@
+/*
+ *  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.core.metamodel.facets.object.domainobject;
+
+
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.services.HasTransactionId;
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.commons.config.IsisConfigurationAware;
+import org.apache.isis.core.metamodel.adapter.QuerySubmitter;
+import org.apache.isis.core.metamodel.adapter.QuerySubmitterAware;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManagerAware;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facetapi.FeatureType;
+import org.apache.isis.core.metamodel.facets.Annotations;
+import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjector;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjectorAware;
+import org.apache.isis.core.metamodel.spec.SpecificationLoaderAware;
+
+
+public class DomainObjectFactory extends FacetFactoryAbstract implements IsisConfigurationAware, AdapterManagerAware, ServicesInjectorAware, SpecificationLoaderAware, QuerySubmitterAware {
+
+    private IsisConfiguration configuration;
+    private AdapterManager adapterManager;
+    private ServicesInjector servicesInjector;
+    private QuerySubmitter querySubmitter;
+
+    public DomainObjectFactory() {
+        super(FeatureType.OBJECTS_ONLY);
+    }
+
+    @Override
+    public void process(ProcessClassContext processClassContext) {
+
+        final Class<?> cls = processClassContext.getCls();
+        final DomainObject domainObject = Annotations.getAnnotation(cls, DomainObject.class);
+        if(domainObject == null) {
+            return;
+        }
+
+        processAuditing(processClassContext);
+        processPublishing(processClassContext);
+        processAutoComplete(processClassContext);
+        processBounded(processClassContext);
+        processEditing(processClassContext);
+        processObjectType(processClassContext);
+        processViewModel(processClassContext);
+    }
+
+    private void processAuditing(ProcessClassContext processClassContext) {
+        final Class<?> cls = processClassContext.getCls();
+        final DomainObject domainObject = Annotations.getAnnotation(cls, DomainObject.class);
+        final FacetHolder facetHolder = processClassContext.getFacetHolder();
+
+        //
+        // this rule originally implemented only in AuditableFacetFromConfigurationFactory
+        // but think should apply in general
+        //
+        if(HasTransactionId.class.isAssignableFrom(cls)) {
+            // do not install on any implementation of HasTransactionId
+            // (ie commands, audit entries, published events).
+            return;
+        }
+
+        FacetUtil.addFacet(AuditableFacetForDomainObjectAnnotation.create(domainObject, configuration, facetHolder));
+    }
+
+
+    private void processPublishing(ProcessClassContext processClassContext) {
+        final Class<?> cls = processClassContext.getCls();
+        final DomainObject domainObject = Annotations.getAnnotation(cls, DomainObject.class);
+        final FacetHolder facetHolder = processClassContext.getFacetHolder();
+
+        FacetUtil.addFacet(PublishedObjectFacetForDomainObjectAnnotation.create(domainObject, configuration, facetHolder));
+    }
+
+    private void processAutoComplete(final ProcessClassContext processClassContext) {
+        final Class<?> cls = processClassContext.getCls();
+        final DomainObject domainObject = Annotations.getAnnotation(cls, DomainObject.class);
+        final FacetHolder facetHolder = processClassContext.getFacetHolder();
+
+        FacetUtil.addFacet(AutoCompleteFacetForDomainObjectAnnotation.create(domainObject, getSpecificationLoader(), adapterManager, servicesInjector, facetHolder));
+    }
+
+    private void processBounded(final ProcessClassContext processClassContext) {
+        final Class<?> cls = processClassContext.getCls();
+        final DomainObject domainObject = Annotations.getAnnotation(cls, DomainObject.class);
+        final FacetHolder facetHolder = processClassContext.getFacetHolder();
+
+        FacetUtil.addFacet(ChoicesFacetForDomainObjectAnnotation.create(domainObject, querySubmitter, facetHolder));
+    }
+
+    private void processEditing(final ProcessClassContext processClassContext) {
+        final Class<?> cls = processClassContext.getCls();
+        final DomainObject domainObject = Annotations.getAnnotation(cls, DomainObject.class);
+        final FacetHolder facetHolder = processClassContext.getFacetHolder();
+
+        FacetUtil.addFacet(ImmutableFacetForDomainObjectAnnotation.create(domainObject, configuration, facetHolder));
+    }
+
+    private void processObjectType(final ProcessClassContext processClassContext) {
+        final Class<?> cls = processClassContext.getCls();
+        final DomainObject domainObject = Annotations.getAnnotation(cls, DomainObject.class);
+        final FacetHolder facetHolder = processClassContext.getFacetHolder();
+
+        FacetUtil.addFacet(ObjectSpecIdFacetForDomainObjectAnnotation.create(domainObject, facetHolder));
+    }
+
+    private void processViewModel(final ProcessClassContext processClassContext) {
+        final Class<?> cls = processClassContext.getCls();
+        final DomainObject domainObject = Annotations.getAnnotation(cls, DomainObject.class);
+        final FacetHolder facetHolder = processClassContext.getFacetHolder();
+
+        FacetUtil.addFacet(ViewModelFacetForDomainObjectAnnotation.create(domainObject, getSpecificationLoader(), adapterManager, servicesInjector, facetHolder));
+    }
+
+
+    @Override
+    public void setConfiguration(IsisConfiguration configuration) {
+        this.configuration = configuration;
+    }
+
+
+    @Override
+    public void setAdapterManager(AdapterManager adapterManager) {
+        this.adapterManager = adapterManager;
+    }
+
+    @Override
+    public void setServicesInjector(ServicesInjector servicesInjector) {
+        this.servicesInjector = servicesInjector;
+    }
+
+    @Override
+    public void setQuerySubmitter(final QuerySubmitter querySubmitter) {
+        this.querySubmitter = querySubmitter;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/EditingObjectsConfiguration.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/EditingObjectsConfiguration.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/EditingObjectsConfiguration.java
new file mode 100644
index 0000000..20b6972
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/EditingObjectsConfiguration.java
@@ -0,0 +1,23 @@
+package org.apache.isis.core.metamodel.facets.object.domainobject;
+
+import org.apache.isis.core.commons.config.IsisConfiguration;
+
+public enum EditingObjectsConfiguration {
+    ALL,
+    NONE;
+
+    private static final String EDIT_OBJECTS_KEY = "isis.services.editing.objects";
+
+    public static EditingObjectsConfiguration parse(IsisConfiguration configuration) {
+        final String configuredValue = configuration.getString(EDIT_OBJECTS_KEY);
+        return EditingObjectsConfiguration.parse(configuredValue);
+    }
+
+    private static EditingObjectsConfiguration parse(final String value) {
+        if ("all".equalsIgnoreCase(value)) {
+            return ALL;
+        } else {
+            return NONE;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/ImmutableFacetForDomainObjectAnnotation.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/ImmutableFacetForDomainObjectAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/ImmutableFacetForDomainObjectAnnotation.java
new file mode 100644
index 0000000..9142dcf
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/ImmutableFacetForDomainObjectAnnotation.java
@@ -0,0 +1,83 @@
+/*
+ *  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.core.metamodel.facets.object.domainobject;
+
+import com.google.common.base.Strings;
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.annotation.EditPolicy;
+import org.apache.isis.applib.annotation.When;
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facets.object.immutable.ImmutableFacet;
+import org.apache.isis.core.metamodel.facets.object.immutable.ImmutableFacetAbstract;
+
+public class ImmutableFacetForDomainObjectAnnotation extends ImmutableFacetAbstract {
+
+    private final String reason;
+
+    public static ImmutableFacet create(
+            final DomainObject domainObject,
+            final IsisConfiguration configuration,
+            final FacetHolder holder) {
+
+        final EditPolicy editPolicy = domainObject.editing();
+        final String disabledReason = domainObject.editingDisabledReason();
+        switch (editPolicy) {
+            case AS_CONFIGURED:
+
+                if(holder.containsDoOpFacet(ImmutableFacet.class)) {
+                    // do not replace
+                    return null;
+                }
+
+                final EditingObjectsConfiguration setting = EditingObjectsConfiguration.parse(configuration);
+                return setting == EditingObjectsConfiguration.NONE
+                        ? new ImmutableFacetForDomainObjectAnnotation(disabledReason, holder)
+                        : null;
+            case DISABLED:
+                return new ImmutableFacetForDomainObjectAnnotation(disabledReason, holder);
+            case ENABLED:
+                return null;
+        }
+        return null;
+    }
+
+    public ImmutableFacetForDomainObjectAnnotation(final String reason, final FacetHolder holder) {
+        super(When.ALWAYS, holder);
+        this.reason = reason;
+    }
+
+    @Override
+    public String disabledReason(final ObjectAdapter targetAdapter) {
+        return !Strings.isNullOrEmpty(reason)
+                ? reason
+                : super.disabledReason(targetAdapter);
+    }
+
+    @Override
+    public void copyOnto(final FacetHolder holder) {
+        final Facet facet = new ImmutableFacetForDomainObjectAnnotation(reason, holder);
+        FacetUtil.addFacet(facet);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/ObjectSpecIdFacetForDomainObjectAnnotation.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/ObjectSpecIdFacetForDomainObjectAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/ObjectSpecIdFacetForDomainObjectAnnotation.java
new file mode 100644
index 0000000..963b526
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/ObjectSpecIdFacetForDomainObjectAnnotation.java
@@ -0,0 +1,45 @@
+/*
+ *  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.core.metamodel.facets.object.domainobject;
+
+import com.google.common.base.Strings;
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.object.objectspecid.ObjectSpecIdFacet;
+import org.apache.isis.core.metamodel.facets.object.objectspecid.ObjectSpecIdFacetAbstract;
+
+public class ObjectSpecIdFacetForDomainObjectAnnotation extends ObjectSpecIdFacetAbstract {
+
+    public static ObjectSpecIdFacet create(
+            final DomainObject domainObject,
+            final FacetHolder holder) {
+
+        final String objectType = domainObject.objectType();
+        if(Strings.isNullOrEmpty(objectType)) {
+            return null;
+        }
+        return new ObjectSpecIdFacetForDomainObjectAnnotation(objectType, holder);
+    }
+
+    private ObjectSpecIdFacetForDomainObjectAnnotation(final String value,
+                                                      final FacetHolder holder) {
+        super(value, holder);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/PublishObjectsConfiguration.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/PublishObjectsConfiguration.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/PublishObjectsConfiguration.java
new file mode 100644
index 0000000..d77485c
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/PublishObjectsConfiguration.java
@@ -0,0 +1,24 @@
+package org.apache.isis.core.metamodel.facets.object.domainobject;
+
+import org.apache.isis.core.commons.config.IsisConfiguration;
+
+public enum PublishObjectsConfiguration {
+    ALL,
+    NONE;
+
+    private static final String PUBLISH_OBJECTS_KEY = "isis.services.publish.objects";
+
+    public static PublishObjectsConfiguration parse(IsisConfiguration configuration) {
+        final String configuredValue = configuration.getString(PUBLISH_OBJECTS_KEY);
+        return PublishObjectsConfiguration.parse(configuredValue);
+    }
+
+    private static PublishObjectsConfiguration parse(final String value) {
+        if ("all".equalsIgnoreCase(value)) {
+            return ALL;
+        } else {
+            return NONE;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/93a81dba/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/PublishedObjectFacetForDomainObjectAnnotation.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/PublishedObjectFacetForDomainObjectAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/PublishedObjectFacetForDomainObjectAnnotation.java
new file mode 100644
index 0000000..a2b5329
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/PublishedObjectFacetForDomainObjectAnnotation.java
@@ -0,0 +1,100 @@
+/*
+ *  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.core.metamodel.facets.object.domainobject;
+
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.annotation.PublishedObject;
+import org.apache.isis.applib.annotation.PublishingPolicy;
+import org.apache.isis.applib.services.publish.EventPayload;
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.object.publishedobject.PublishedObjectFacet;
+import org.apache.isis.core.metamodel.facets.object.publishedobject.PublishedObjectFacetAbstract;
+
+public class PublishedObjectFacetForDomainObjectAnnotation extends PublishedObjectFacetAbstract {
+
+    public static PublishedObjectFacet create(
+            final DomainObject domainObject,
+            final IsisConfiguration configuration,
+            final FacetHolder holder) {
+
+        final PublishingPolicy publishingPolicy = domainObject.publishing();
+
+        switch (publishingPolicy) {
+            case AS_CONFIGURED:
+
+                if(holder.containsDoOpFacet(PublishedObjectFacet.class)) {
+                    // do not replace
+                    return null;
+                }
+
+                final PublishObjectsConfiguration setting = PublishObjectsConfiguration.parse(configuration);
+                return setting == PublishObjectsConfiguration.ALL
+                        ? new PublishedObjectFacetForDomainObjectAnnotation(newPayloadFactory(domainObject.publishingPayloadFactory()), holder)
+                        : null;
+            case DISABLED:
+                return null;
+            case ENABLED:
+                return new PublishedObjectFacetForDomainObjectAnnotation(newPayloadFactory(domainObject.publishingPayloadFactory()), holder);
+        }
+        return null;
+    }
+
+    private static DomainObject.PublishingPayloadFactory newPayloadFactory(final Class<? extends DomainObject.PublishingPayloadFactory> value) {
+        if(value == null) {
+            return null;
+        }
+        try {
+            return value.newInstance();
+        } catch (final InstantiationException e) {
+            return null;
+        } catch (final IllegalAccessException e) {
+            return null;
+        }
+    }
+
+
+    private PublishedObjectFacetForDomainObjectAnnotation(DomainObject.PublishingPayloadFactory publishingPayloadFactory, final FacetHolder holder) {
+        super(legacyPayloadFactoryFor(publishingPayloadFactory), holder);
+    }
+
+    private static PublishedObject.PayloadFactory legacyPayloadFactoryFor(DomainObject.PublishingPayloadFactory publishingPayloadFactory) {
+        if(publishingPayloadFactory instanceof DomainObject.PublishingPayloadFactory.Adapter) {
+            final DomainObject.PublishingPayloadFactory.Adapter adapter = (DomainObject.PublishingPayloadFactory.Adapter) publishingPayloadFactory;
+            return adapter.getPayloadFactory();
+        }
+        return new LegacyAdapter(publishingPayloadFactory);
+    }
+
+    private static class LegacyAdapter implements PublishedObject.PayloadFactory {
+
+        private final DomainObject.PublishingPayloadFactory payloadFactory;
+
+        LegacyAdapter(final DomainObject.PublishingPayloadFactory payloadFactory) {
+            this.payloadFactory = payloadFactory;
+        }
+
+        @Override
+        public EventPayload payloadFor(Object changedObject, PublishedObject.ChangeKind changeKind) {
+            return payloadFactory.payloadFor(changedObject, DomainObject.PublishingChangeKind.from(changeKind));
+        }
+    }
+
+}