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/24 20:21:26 UTC

[1/2] git commit: ISIS-809: view models using @ViewModel annotation (builds memento from all read/write properties, provided not annotated with either @NotPersistable or @Programmatic)

Repository: isis
Updated Branches:
  refs/heads/master db0cdef8e -> fa1876c02


ISIS-809: view models using @ViewModel annotation (builds memento from all read/write properties, provided not annotated with either @NotPersistable or @Programmatic)


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

Branch: refs/heads/master
Commit: c88a590eb5317024a6e9ea8a4e9404a124347b5f
Parents: db0cdef
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Wed Sep 24 16:38:41 2014 +0100
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Wed Sep 24 16:38:41 2014 +0100

----------------------------------------------------------------------
 .../isis/applib/DomainObjectContainer.java      |   5 +
 .../isis/applib/annotation/ViewModel.java       |  39 +++++
 .../services/bookmark/BookmarkService.java      |   4 +-
 .../applib/services/memento/MementoService.java |   1 -
 .../metamodel/adapter/DomainObjectServices.java |   2 +
 .../metamodel/adapter/mgr/AdapterManager.java   |  11 ++
 .../annotation/ViewModelFacetAnnotation.java    | 167 +++++++++++++++++++
 .../ViewModelFacetAnnotationFactory.java        |  62 +++++++
 .../noruntime/RuntimeContextNoRuntime.java      |  15 ++
 .../container/DomainObjectContainerDefault.java |  20 +++
 .../dflt/ProgrammingModelFacetsJava5.java       |  96 +++++------
 .../spi/DataNucleusIdentifierGenerator.java     |  18 +-
 .../internal/RuntimeContextFromSession.java     |  30 ++--
 .../system/persistence/AdapterManagerSpi.java   |   1 -
 .../system/persistence/OidGenerator.java        |  13 +-
 .../system/persistence/PersistenceSession.java  |  15 ++
 .../dom/src/main/java/app/ToDoItemAnalysis.java |  10 +-
 .../java/app/ToDoItemsByCategoryViewModel.java  |  24 ++-
 .../java/app/ToDoItemsByDateRangeViewModel.java |  25 +--
 19 files changed, 441 insertions(+), 117 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/c88a590e/core/applib/src/main/java/org/apache/isis/applib/DomainObjectContainer.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/DomainObjectContainer.java b/core/applib/src/main/java/org/apache/isis/applib/DomainObjectContainer.java
index 170e86d..61aa27f 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/DomainObjectContainer.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/DomainObjectContainer.java
@@ -170,6 +170,11 @@ public interface DomainObjectContainer {
     <T extends ViewModel> T newViewModelInstance(final Class<T> ofType, final String memento);
 
     /**
+     * Recognizes/registers an existing object as a view model.
+     */
+    <T> T existingViewModelInstance(final T viewModelInstance);
+
+    /**
      * Create a new instance that will be persisted as part of the specified
      * parent (ie will be a part of a larger aggregate).
      * 

http://git-wip-us.apache.org/repos/asf/isis/blob/c88a590e/core/applib/src/main/java/org/apache/isis/applib/annotation/ViewModel.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/ViewModel.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/ViewModel.java
new file mode 100644
index 0000000..b21ef20
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/ViewModel.java
@@ -0,0 +1,39 @@
+/*
+ *  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;
+
+import java.lang.annotation.*;
+
+/**
+ * Indicates that an instance should be treated as a view model.
+ *
+ * <p>
+ *     All of its read/write and non-{@link Programmatic} properties (not collections) will be included in the
+ *     view model's memento; in other words as returned and marshalled by
+ *     {@link org.apache.isis.applib.ViewModel#viewModelMemento()}.
+ * </p>
+ */
+@Inherited
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ViewModel {
+
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/c88a590e/core/applib/src/main/java/org/apache/isis/applib/services/bookmark/BookmarkService.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/bookmark/BookmarkService.java b/core/applib/src/main/java/org/apache/isis/applib/services/bookmark/BookmarkService.java
index 0afc2c0..74b39e2 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/bookmark/BookmarkService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/bookmark/BookmarkService.java
@@ -36,13 +36,13 @@ public interface BookmarkService {
     Object lookup(BookmarkHolder bookmarkHolder);
 
     @Programmatic
-    Object lookup(Bookmark bookmarkHolder);
+    Object lookup(Bookmark bookmark);
 
     /**
      * As {@link #lookup(Bookmark)}, but downcasting to the specified type.
      */
     @Programmatic
-    <T> T lookup(Bookmark bookmarkHolder, Class<T> cls);
+    <T> T lookup(Bookmark bookmark, Class<T> cls);
 
     @Programmatic
     Bookmark bookmarkFor(Object domainObject);

http://git-wip-us.apache.org/repos/asf/isis/blob/c88a590e/core/applib/src/main/java/org/apache/isis/applib/services/memento/MementoService.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/memento/MementoService.java b/core/applib/src/main/java/org/apache/isis/applib/services/memento/MementoService.java
index 3ee8505..353b19d 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/memento/MementoService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/memento/MementoService.java
@@ -17,7 +17,6 @@
 package org.apache.isis.applib.services.memento;
 
 import java.util.Set;
-
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 

http://git-wip-us.apache.org/repos/asf/isis/blob/c88a590e/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/DomainObjectServices.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/DomainObjectServices.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/DomainObjectServices.java
index f559c4c..ff30bc8 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/DomainObjectServices.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/DomainObjectServices.java
@@ -42,6 +42,8 @@ public interface DomainObjectServices extends Injectable {
 
     ObjectAdapter createViewModelInstance(ObjectSpecification spec, String memento);
 
+    ObjectAdapter existingViewModelInstance(Object viewModelPojo);
+
     /**
      * Create an instance of an aggregated object that will be persisted within the
      * parent adapter.

http://git-wip-us.apache.org/repos/asf/isis/blob/c88a590e/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/mgr/AdapterManager.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/mgr/AdapterManager.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/mgr/AdapterManager.java
index d4dedc9..03423d1 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/mgr/AdapterManager.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/mgr/AdapterManager.java
@@ -201,4 +201,15 @@ public interface AdapterManager extends Injectable {
      */
     public ObjectAdapter adapterFor(final Object pojo, final ObjectAdapter parentAdapter, OneToManyAssociation collection);
 
+
+    /**
+     * Enable viewModelFacetAnnotation to 'temporarily' map an existing pojo to an oid.
+     */
+    ObjectAdapter mapRecreatedPojo(Oid oid, Object recreatedPojo);
+
+    /**
+     * Enable viewModelFacetAnnotation to remove a 'temporarily' mapped an adapter for a pojo.
+     */
+    void removeAdapter(ObjectAdapter adapter);
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/c88a590e/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/annotation/ViewModelFacetAnnotation.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/annotation/ViewModelFacetAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/annotation/ViewModelFacetAnnotation.java
new file mode 100644
index 0000000..ba21e2b
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/annotation/ViewModelFacetAnnotation.java
@@ -0,0 +1,167 @@
+/*
+ *  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.viewmodel.annotation;
+
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+import org.apache.isis.applib.ViewModel;
+import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.applib.services.bookmark.BookmarkService;
+import org.apache.isis.applib.services.memento.MementoService;
+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.metamodel.adapter.oid.RootOidDefault;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacetAbstract;
+import org.apache.isis.core.metamodel.facets.properties.update.modify.PropertySetterFacet;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjector;
+import org.apache.isis.core.metamodel.spec.ObjectSpecId;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.SpecificationLoader;
+import org.apache.isis.core.metamodel.spec.feature.Contributed;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+
+public class ViewModelFacetAnnotation extends ViewModelFacetAbstract {
+
+    private final SpecificationLoader specificationLoader;
+    private final ServicesInjector servicesInjector;
+    private final AdapterManager adapterManager;
+
+    public ViewModelFacetAnnotation(
+            final FacetHolder holder,
+            final SpecificationLoader specificationLoader,
+            final AdapterManager adapterManager,
+            final ServicesInjector servicesInjector) {
+        super(holder);
+        this.specificationLoader = specificationLoader;
+        this.servicesInjector = servicesInjector;
+        this.adapterManager = adapterManager;
+    }
+
+    @Override
+    public void initialize(Object viewModelPojo, String mementoStr) {
+
+        final MementoService mementoService = servicesInjector.lookupService(MementoService.class);
+        final BookmarkService bookmarkService = servicesInjector.lookupService(BookmarkService.class);
+
+        final MementoService.Memento memento = mementoService.parse(mementoStr);
+
+        final Set<String> mementoKeys = memento.keySet();
+
+        // manually recreate the adapter in order to be able to query state via the metamodel
+        ObjectAdapter viewModelAdapter = adapterManager.getAdapterFor(viewModelPojo);
+        if(viewModelAdapter == null) {
+            final ObjectSpecification objectSpecification = specificationLoader.loadSpecification(viewModelPojo.getClass());
+            final ObjectSpecId objectSpecId = objectSpecification.getSpecId();
+            viewModelAdapter = adapterManager.mapRecreatedPojo(new RootOidDefault(objectSpecId, mementoStr, Oid.State.VIEWMODEL), viewModelPojo);
+        }
+
+        final ObjectSpecification spec = viewModelAdapter.getSpecification();
+        final List<OneToOneAssociation> properties = spec.getProperties(Contributed.EXCLUDED);
+        for (OneToOneAssociation property : properties) {
+            final String propertyId = property.getId();
+
+            Object propertyValue = null;
+
+            if(mementoKeys.contains(propertyId)) {
+                final Class<?> propertyType = property.getSpecification().getCorrespondingClass();
+                propertyValue = memento.get(propertyId, propertyType);
+            } else if(mementoKeys.contains(propertyId + ".bookmark")) {
+                final Bookmark propertyValueBookmark = memento.get(propertyId, Bookmark.class);
+                propertyValue = bookmarkService.lookup(propertyValueBookmark);
+            }
+
+            if(propertyValue != null) {
+                property.set(viewModelAdapter, adapterManager.adapterFor(propertyValue));
+            }
+        }
+    }
+    
+    @Override
+    public String memento(Object viewModelPojo) {
+
+        final MementoService mementoService = servicesInjector.lookupService(MementoService.class);
+        final BookmarkService bookmarkService = servicesInjector.lookupService(BookmarkService.class);
+
+        final MementoService.Memento memento = mementoService.create();
+
+        // this is horrible, but there's a catch-22 here...
+        // we need an adapter in order to query the state of the object via the metamodel, on the other hand
+        // we can't create an adapter without the identifier, which is what we're trying to derive
+        // so... we create a temporary transient adapter, use it to wrap this adapter and interrogate this pojo,
+        // then throw away that adapter (remove from the adapter map)
+        boolean createdTemporaryAdapter = false;
+        ObjectAdapter viewModelAdapter = adapterManager.getAdapterFor(viewModelPojo);
+        if(viewModelAdapter == null) {
+            final ObjectSpecification objectSpecification = specificationLoader.loadSpecification(viewModelPojo.getClass());
+            final ObjectSpecId objectSpecId = objectSpecification.getSpecId();
+            viewModelAdapter = adapterManager.mapRecreatedPojo(RootOidDefault.create(objectSpecId, UUID.randomUUID().toString()), viewModelPojo);
+
+            createdTemporaryAdapter = true;
+        }
+
+        try {
+            final ObjectSpecification spec = viewModelAdapter.getSpecification();
+            final List<OneToOneAssociation> properties = spec.getProperties(Contributed.EXCLUDED);
+            for (OneToOneAssociation property : properties) {
+                // ignore read-only
+                if(!property.containsDoOpFacet(PropertySetterFacet.class)) {
+                    continue;
+                }
+                // ignore those explicitly annotated as @NotPersisted
+                if(property.isNotPersisted()) {
+                    continue;
+                }
+
+                // otherwise, include
+                final ObjectAdapter propertyValueAdapter = property.get(adapterManager.adapterFor(viewModelPojo));
+                if(propertyValueAdapter != null) {
+                    final Object propertyValue = propertyValueAdapter.getObject();
+                    if(mementoService.canSet(propertyValue)) {
+                        memento.set(property.getId(), propertyValue);
+                    } else {
+                        final Bookmark propertyValueBookmark = bookmarkService.bookmarkFor(propertyValue);
+                        memento.set(property.getId() + ".bookmark", propertyValueBookmark);
+                    }
+                }
+            }
+            return memento.asString();
+        } finally {
+            if(createdTemporaryAdapter) {
+                adapterManager.removeAdapter(viewModelAdapter);
+            }
+        }
+    }
+
+    @Override
+    public boolean isCloneable(Object pojo) {
+        return pojo != null && pojo instanceof ViewModel.Cloneable;
+    }
+
+    @Override
+    public Object clone(Object pojo) {
+        ViewModel.Cloneable viewModelCloneable = (ViewModel.Cloneable) pojo;
+        return viewModelCloneable.clone();
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/c88a590e/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/annotation/ViewModelFacetAnnotationFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/annotation/ViewModelFacetAnnotationFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/annotation/ViewModelFacetAnnotationFactory.java
new file mode 100644
index 0000000..a62e87e
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/annotation/ViewModelFacetAnnotationFactory.java
@@ -0,0 +1,62 @@
+/*
+ *  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.viewmodel.annotation;
+
+import org.apache.isis.applib.annotation.ViewModel;
+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.facets.object.viewmodel.ViewModelFacet;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjector;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjectorAware;
+
+public class ViewModelFacetAnnotationFactory extends FacetFactoryAbstract implements ServicesInjectorAware, AdapterManagerAware {
+
+    private ServicesInjector servicesInjector;
+    private AdapterManager adapterManager;
+
+    public ViewModelFacetAnnotationFactory() {
+        super(FeatureType.OBJECTS_ONLY);
+    }
+
+    @Override
+    public void process(final ProcessClassContext processClassContext) {
+        final ViewModel annotation = Annotations.getAnnotation(processClassContext.getCls(), ViewModel.class);
+        FacetUtil.addFacet(create(annotation, processClassContext.getFacetHolder()));
+    }
+
+    private ViewModelFacet create(final ViewModel annotation, final FacetHolder holder) {
+        return annotation != null ? new ViewModelFacetAnnotation(holder, getSpecificationLoader(), adapterManager, servicesInjector) : null;
+    }
+
+    @Override
+    public void setServicesInjector(ServicesInjector servicesInjector) {
+        this.servicesInjector = servicesInjector;
+    }
+
+    @Override
+    public void setAdapterManager(AdapterManager adapterManager) {
+        this.adapterManager = adapterManager;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/c88a590e/core/metamodel/src/main/java/org/apache/isis/core/metamodel/runtimecontext/noruntime/RuntimeContextNoRuntime.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/runtimecontext/noruntime/RuntimeContextNoRuntime.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/runtimecontext/noruntime/RuntimeContextNoRuntime.java
index f9dfa76..c2d5a06 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/runtimecontext/noruntime/RuntimeContextNoRuntime.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/runtimecontext/noruntime/RuntimeContextNoRuntime.java
@@ -128,6 +128,16 @@ public class RuntimeContextNoRuntime extends RuntimeContextAbstract {
             }
 
             @Override
+            public ObjectAdapter mapRecreatedPojo(Oid oid, Object recreatedPojo) {
+                throw new UnsupportedOperationException("Not supported by this implementation of RuntimeContext");
+            }
+
+            @Override
+            public void removeAdapter(ObjectAdapter adapter) {
+                throw new UnsupportedOperationException("Not supported by this implementation of RuntimeContext");
+            }
+
+            @Override
             public ObjectAdapter adapterFor(final Object domainObject) {
                 throw new UnsupportedOperationException("Not supported by this implementation of RuntimeContext");
             }
@@ -193,6 +203,11 @@ public class RuntimeContextNoRuntime extends RuntimeContextAbstract {
             }
 
             @Override
+            public ObjectAdapter existingViewModelInstance(Object viewModelPojo) {
+                throw new UnsupportedOperationException("Not supported by this implementation of RuntimeContext");
+            }
+
+            @Override
             public ObjectAdapter createAggregatedInstance(final ObjectSpecification spec, final ObjectAdapter parent) {
                 throw new UnsupportedOperationException("Not supported by this implementation of RuntimeContext");
             }

http://git-wip-us.apache.org/repos/asf/isis/blob/c88a590e/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/container/DomainObjectContainerDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/container/DomainObjectContainerDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/container/DomainObjectContainerDefault.java
index e6c4f7c..cc73282 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/container/DomainObjectContainerDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/container/DomainObjectContainerDefault.java
@@ -113,6 +113,22 @@ public class  DomainObjectContainerDefault implements DomainObjectContainer, Que
         }
     }
 
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T> T existingViewModelInstance(final T viewModelPojo) {
+        final Class<?> viewModelClass = viewModelPojo.getClass();
+        final ObjectSpecification spec = getSpecificationLookup().loadSpecification(viewModelClass);
+        if (!spec.containsFacet(ViewModelFacet.class)) {
+            throw new IsisException("Type must be a ViewModel: " + viewModelClass);
+        }
+        final ObjectAdapter adapter = doExistingViewModelInstance(viewModelPojo);
+        if(adapter.getOid().isViewModel()) {
+            return (T)adapter.getObject();
+        } else {
+            throw new IsisException("Object is not a ViewModel (imple,e");
+        }
+    }
+
     @Override
     @SuppressWarnings("unchecked")
     public <T> T newAggregatedInstance(final Object parent, final Class<T> ofClass) {
@@ -163,6 +179,10 @@ public class  DomainObjectContainerDefault implements DomainObjectContainer, Que
         return getDomainObjectServices().createViewModelInstance(spec, memento);
     }
 
+    protected ObjectAdapter doExistingViewModelInstance(final Object viewModelPojo) {
+        return getDomainObjectServices().existingViewModelInstance(viewModelPojo);
+    }
+
     private ObjectAdapter doCreateAggregatedInstance(final ObjectSpecification spec, final Object parent) {
         final ObjectAdapter parentAdapter = getAdapterManager().getAdapterFor(parent);
         return getDomainObjectServices().createAggregatedInstance(spec, parentAdapter);

http://git-wip-us.apache.org/repos/asf/isis/blob/c88a590e/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java b/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
index 93fee37..70bd53f 100644
--- a/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
+++ b/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
@@ -32,13 +32,15 @@ import org.apache.isis.core.metamodel.facets.actions.notinservicemenu.annotation
 import org.apache.isis.core.metamodel.facets.actions.notinservicemenu.method.NotInServiceMenuFacetViaMethodFactory;
 import org.apache.isis.core.metamodel.facets.actions.prototype.annotation.PrototypeFacetAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.actions.publish.annotation.PublishedActionFacetAnnotationFactory;
+import org.apache.isis.core.metamodel.facets.actions.semantics.annotations.actionsemantics.ActionSemanticsFacetAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.actions.semantics.annotations.idempotent.IdempotentFacetAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.actions.semantics.annotations.queryonly.QueryOnlyFacetAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.actions.semantics.fallback.ActionSemanticsFacetFallbackToNonIdempotentFactory;
-import org.apache.isis.core.metamodel.facets.actions.semantics.annotations.actionsemantics.ActionSemanticsFacetAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.actions.typeof.annotation.TypeOfFacetOnActionAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.actions.validate.method.ActionValidationFacetViaMethodFactory;
 import org.apache.isis.core.metamodel.facets.collections.accessor.CollectionAccessorFacetViaAccessorFactory;
+import org.apache.isis.core.metamodel.facets.collections.clear.CollectionClearFacetFactory;
+import org.apache.isis.core.metamodel.facets.collections.collection.CollectionFacetFactory;
 import org.apache.isis.core.metamodel.facets.collections.disabled.fromimmutable.DisabledFacetOnCollectionDerivedFromImmutableFactory;
 import org.apache.isis.core.metamodel.facets.collections.interaction.CollectionInteractionFacetFactory;
 import org.apache.isis.core.metamodel.facets.collections.modify.CollectionAddToRemoveFromAndValidateFacetFactory;
@@ -47,9 +49,11 @@ import org.apache.isis.core.metamodel.facets.collections.paged.annotation.PagedF
 import org.apache.isis.core.metamodel.facets.collections.parented.ParentedFacetSinceCollectionFactory;
 import org.apache.isis.core.metamodel.facets.collections.sortedby.annotation.SortedByFacetAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.collections.typeof.annotation.TypeOfFacetOnCollectionAnnotationFactory;
+import org.apache.isis.core.metamodel.facets.fallback.FallbackFacetFactory;
 import org.apache.isis.core.metamodel.facets.members.cssclass.annotprop.CssClassFacetOnMemberFactory;
 import org.apache.isis.core.metamodel.facets.members.describedas.annotprop.DescribedAsFacetOnMemberFactory;
 import org.apache.isis.core.metamodel.facets.members.describedas.staticmethod.DescribedAsFacetStaticMethodFactory;
+import org.apache.isis.core.metamodel.facets.members.disabled.annotprop.DisabledFacetFactory;
 import org.apache.isis.core.metamodel.facets.members.disabled.forsession.DisableForSessionFacetViaMethodFactory;
 import org.apache.isis.core.metamodel.facets.members.disabled.method.DisableForContextFacetViaMethodFactory;
 import org.apache.isis.core.metamodel.facets.members.disabled.staticmethod.DisabledFacetStaticMethodFacetFactory;
@@ -59,49 +63,68 @@ import org.apache.isis.core.metamodel.facets.members.hidden.method.HideForContex
 import org.apache.isis.core.metamodel.facets.members.hidden.staticmethod.HiddenFacetStaticMethodFactory;
 import org.apache.isis.core.metamodel.facets.members.named.annotprop.NamedFacetOnMemberFactory;
 import org.apache.isis.core.metamodel.facets.members.named.staticmethod.NamedFacetStaticMethodFactory;
+import org.apache.isis.core.metamodel.facets.members.order.annotprop.MemberOrderFacetFactory;
 import org.apache.isis.core.metamodel.facets.members.render.annotprop.RenderFacetOrResolveFactory;
+import org.apache.isis.core.metamodel.facets.object.actionorder.annotation.ActionOrderFacetAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.object.audit.annotation.AuditableFacetFromAuditedAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.object.audit.configuration.AuditableFacetFromConfigurationFactory;
 import org.apache.isis.core.metamodel.facets.object.audit.markerifc.AuditableFacetMarkerInterfaceFactory;
 import org.apache.isis.core.metamodel.facets.object.autocomplete.annotation.AutoCompleteFacetAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.object.bookmarkpolicy.bookmarkable.BookmarkPolicyFacetViaBookmarkableAnnotationFactory;
-import org.apache.isis.core.metamodel.facets.object.choices.boundedmarkerifc.ChoicesFacetFromBoundedMarkerInterfaceFactory;
+import org.apache.isis.core.metamodel.facets.object.callbacks.create.CreatedCallbackFacetFactory;
+import org.apache.isis.core.metamodel.facets.object.callbacks.load.LoadCallbackFacetFactory;
+import org.apache.isis.core.metamodel.facets.object.callbacks.persist.PersistCallbackFacetFactory;
+import org.apache.isis.core.metamodel.facets.object.callbacks.persist.PersistCallbackViaSaveMethodFacetFactory;
+import org.apache.isis.core.metamodel.facets.object.callbacks.remove.RemoveCallbackFacetFactory;
+import org.apache.isis.core.metamodel.facets.object.callbacks.update.UpdateCallbackFacetFactory;
 import org.apache.isis.core.metamodel.facets.object.choices.boundedannot.ChoicesFacetFromBoundedAnnotationFactory;
+import org.apache.isis.core.metamodel.facets.object.choices.boundedmarkerifc.ChoicesFacetFromBoundedMarkerInterfaceFactory;
+import org.apache.isis.core.metamodel.facets.object.choices.enums.EnumFacetUsingValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.object.cssclass.annotation.CssClassFacetOnTypeAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.object.defaults.annotcfg.DefaultedFacetAnnotationElseConfigurationFactory;
 import org.apache.isis.core.metamodel.facets.object.describedas.annotation.DescribedAsFacetOnTypeAnnotationFactory;
+import org.apache.isis.core.metamodel.facets.object.dirty.method.DirtyMethodsFacetFactory;
 import org.apache.isis.core.metamodel.facets.object.disabled.method.DisabledObjectFacetViaMethodFactory;
 import org.apache.isis.core.metamodel.facets.object.domainservice.annotation.DomainServiceFacetAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.object.encodeable.annotcfg.EncodableFacetAnnotationElseConfigurationFactory;
 import org.apache.isis.core.metamodel.facets.object.facets.annotation.FacetsFacetAnnotationFactory;
+import org.apache.isis.core.metamodel.facets.object.fieldorder.annotation.FieldOrderFacetAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.object.hidden.annotation.HiddenFacetOnTypeAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.object.hidden.method.HiddenObjectFacetViaMethodFactory;
 import org.apache.isis.core.metamodel.facets.object.icon.method.IconFacetMethodFactory;
+import org.apache.isis.core.metamodel.facets.object.ignore.annotation.RemoveProgrammaticOrIgnoreAnnotationMethodsFacetFactory;
+import org.apache.isis.core.metamodel.facets.object.ignore.isis.RemoveSetDomainObjectContainerMethodFacetFactory;
+import org.apache.isis.core.metamodel.facets.object.ignore.isis.RemoveStaticGettersAndSettersFacetFactory;
 import org.apache.isis.core.metamodel.facets.object.ignore.javalang.*;
+import org.apache.isis.core.metamodel.facets.object.ignore.jdo.RemoveJdoEnhancementTypesFacetFactory;
+import org.apache.isis.core.metamodel.facets.object.ignore.jdo.RemoveJdoPrefixedMethodsFacetFactory;
 import org.apache.isis.core.metamodel.facets.object.immutable.immutableannot.ImmutableFacetAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.object.immutable.immutablemarkerifc.ImmutableFacetMarkerInterfaceFactory;
 import org.apache.isis.core.metamodel.facets.object.mask.annotation.MaskFacetOnTypeAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.object.maxlen.annotation.MaxLengthFacetOnTypeAnnotationFactory;
+import org.apache.isis.core.metamodel.facets.object.membergroups.annotprop.MemberGroupLayoutFacetFactory;
 import org.apache.isis.core.metamodel.facets.object.multiline.annotation.MultiLineFacetOnTypeAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.object.named.annotation.NamedFacetOnTypeAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.object.notpersistable.notpersistableannot.NotPersistableFacetAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.object.notpersistable.notpersistablemarkerifc.NotPersistableFacetMarkerInterfaceFactory;
-import org.apache.isis.core.metamodel.facets.object.objectspecid.classname.ObjectSpecIdFacetDerivedFromClassNameFactory;
 import org.apache.isis.core.metamodel.facets.object.objectspecid.annotation.ObjectFacetSpecIdAnnotationFactory;
-import org.apache.isis.core.metamodel.facets.object.actionorder.annotation.ActionOrderFacetAnnotationFactory;
-import org.apache.isis.core.metamodel.facets.object.fieldorder.annotation.FieldOrderFacetAnnotationFactory;
+import org.apache.isis.core.metamodel.facets.object.objectspecid.classname.ObjectSpecIdFacetDerivedFromClassNameFactory;
 import org.apache.isis.core.metamodel.facets.object.objectvalidprops.impl.ObjectValidPropertiesFacetImplFactory;
+import org.apache.isis.core.metamodel.facets.object.paged.annotation.PagedFacetOnTypeAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.object.parented.aggregated.ParentedFacetSinceAggregatedAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.object.parseable.annotcfg.ParseableFacetAnnotationElseConfigurationFactory;
+import org.apache.isis.core.metamodel.facets.object.plural.annotation.PluralAnnotationFacetFactory;
 import org.apache.isis.core.metamodel.facets.object.plural.staticmethod.PluralFacetMethodFactory;
 import org.apache.isis.core.metamodel.facets.object.publishedobject.annotation.PublishedObjectFacetAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.object.regex.annotation.RegExFacetOnTypeAnnotationFactory;
+import org.apache.isis.core.metamodel.facets.object.title.annotation.TitleAnnotationFacetFactory;
 import org.apache.isis.core.metamodel.facets.object.title.methods.TitleFacetViaMethodsFactory;
 import org.apache.isis.core.metamodel.facets.object.typicallen.annotation.TypicalLengthFacetOnTypeAnnotationFactory;
+import org.apache.isis.core.metamodel.facets.object.validating.mustsatisfyspec.MustSatisfySpecificationOnTypeFacetFactory;
 import org.apache.isis.core.metamodel.facets.object.validating.validateobject.method.ValidateObjectFacetMethodFactory;
 import org.apache.isis.core.metamodel.facets.object.value.annotcfg.ValueFacetAnnotationOrConfigurationFactory;
+import org.apache.isis.core.metamodel.facets.object.viewmodel.annotation.ViewModelFacetAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.object.viewmodel.iface.ViewModelFacetInterfaceFactory;
-import org.apache.isis.core.metamodel.facets.object.paged.annotation.PagedFacetOnTypeAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.param.autocomplete.method.ActionParameterAutoCompleteFacetViaMethodFactory;
 import org.apache.isis.core.metamodel.facets.param.bigdecimal.javaxvaldigits.BigDecimalFacetOnParameterFromJavaxValidationAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.param.choices.enums.ActionParameterChoicesFacetDerivedFromChoicesFacetFactory;
@@ -119,6 +142,7 @@ import org.apache.isis.core.metamodel.facets.param.typicallen.annotation.Typical
 import org.apache.isis.core.metamodel.facets.param.typicallen.fromtype.TypicalLengthFacetOnParameterDerivedFromTypeFacetFactory;
 import org.apache.isis.core.metamodel.facets.param.validating.maskannot.MaskFacetOnParameterAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.param.validating.maxlenannot.MaxLengthFacetOnParameterAnnotationFactory;
+import org.apache.isis.core.metamodel.facets.param.validating.mustsatisfyspec.MustSatisfySpecificationOnParameterFacetFactory;
 import org.apache.isis.core.metamodel.facets.param.validating.regexannot.RegExFacetFacetOnParameterAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.properties.accessor.PropertyAccessorFacetViaAccessorFactory;
 import org.apache.isis.core.metamodel.facets.properties.autocomplete.method.PropertyAutoCompleteFacetMethodFactory;
@@ -133,74 +157,49 @@ import org.apache.isis.core.metamodel.facets.properties.mandatory.annotation.man
 import org.apache.isis.core.metamodel.facets.properties.mandatory.annotation.optional.MandatoryFacetOnPropertyInvertedByOptionalAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.properties.mandatory.dflt.MandatoryFacetOnProperyDefaultFactory;
 import org.apache.isis.core.metamodel.facets.properties.mandatory.staticmethod.MandatoryFacetOnPropertyStaticMethodFactory;
+import org.apache.isis.core.metamodel.facets.properties.multiline.annotation.MultiLineOnPropertyFacetFactory;
 import org.apache.isis.core.metamodel.facets.properties.notpersisted.annotation.NotPersistedFacetOnPropertyAnnotationFactory;
+import org.apache.isis.core.metamodel.facets.properties.renderedasdaybefore.annotation.RenderedAsDayBeforeAnnotationOnPropertyFacetFactory;
+import org.apache.isis.core.metamodel.facets.properties.typicallen.annotation.TypicalLengthOnPropertyFacetFactory;
 import org.apache.isis.core.metamodel.facets.properties.typicallen.fromtype.TypicalLengthFacetOnPropertyDerivedFromTypeFacetFactory;
-import org.apache.isis.core.metamodel.facets.properties.validating.method.PropertyValidateFacetViaMethodFactory;
+import org.apache.isis.core.metamodel.facets.properties.update.PropertyModifyFacetFactory;
+import org.apache.isis.core.metamodel.facets.properties.update.PropertySetAndClearFacetFactory;
 import org.apache.isis.core.metamodel.facets.properties.validating.dflt.PropertyValidateFacetDefaultFactory;
 import org.apache.isis.core.metamodel.facets.properties.validating.maskannot.MaskFacetOnPropertyAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.properties.validating.maxlenannot.MaxLengthFacetOnPropertyAnnotationFactory;
-import org.apache.isis.core.metamodel.facets.properties.validating.regexannot.RegExFacetFacetOnPropertyAnnotationFactory;
-import org.apache.isis.core.metamodel.facets.value.blobs.BlobValueFacetUsingSemanticsProviderFactory;
-import org.apache.isis.core.metamodel.facets.value.bytes.BytePrimitiveValueFacetUsingSemanticsProviderFactory;
-import org.apache.isis.core.metamodel.facets.value.date.DateValueFacetUsingSemanticsProviderFactory;
-import org.apache.isis.core.metamodel.facets.value.dateutil.JavaUtilDateValueFacetUsingSemanticsProviderFactory;
-import org.apache.isis.core.metamodel.facets.value.doubles.DoublePrimitiveValueFacetUsingSemanticsProviderFactory;
-import org.apache.isis.core.metamodel.facets.value.longs.LongWrapperValueFacetUsingSemanticsProviderFactory;
-import org.apache.isis.core.metamodel.facets.value.money.MoneyValueFacetUsingSemanticsProviderFactory;
-import org.apache.isis.core.metamodel.facets.value.password.PasswordValueFacetUsingSemanticsProviderFactory;
-import org.apache.isis.core.metamodel.facets.value.timestampsql.JavaSqlTimeStampValueFacetUsingSemanticsProviderFactory;
-import org.apache.isis.core.metamodel.progmodel.ProgrammingModelAbstract;
-import org.apache.isis.core.metamodel.facets.collections.clear.CollectionClearFacetFactory;
-import org.apache.isis.core.metamodel.facets.collections.collection.CollectionFacetFactory;
-import org.apache.isis.core.metamodel.facets.fallback.FallbackFacetFactory;
-import org.apache.isis.core.metamodel.facets.members.disabled.annotprop.DisabledFacetFactory;
-import org.apache.isis.core.metamodel.facets.members.order.annotprop.MemberOrderFacetFactory;
-import org.apache.isis.core.metamodel.facets.object.callbacks.create.CreatedCallbackFacetFactory;
-import org.apache.isis.core.metamodel.facets.object.callbacks.load.LoadCallbackFacetFactory;
-import org.apache.isis.core.metamodel.facets.object.callbacks.persist.PersistCallbackFacetFactory;
-import org.apache.isis.core.metamodel.facets.object.callbacks.persist.PersistCallbackViaSaveMethodFacetFactory;
-import org.apache.isis.core.metamodel.facets.object.callbacks.remove.RemoveCallbackFacetFactory;
-import org.apache.isis.core.metamodel.facets.object.callbacks.update.UpdateCallbackFacetFactory;
-import org.apache.isis.core.metamodel.facets.object.choices.enums.EnumFacetUsingValueFacetUsingSemanticsProviderFactory;
-import org.apache.isis.core.metamodel.facets.object.dirty.method.DirtyMethodsFacetFactory;
-import org.apache.isis.core.metamodel.facets.object.ignore.annotation.RemoveProgrammaticOrIgnoreAnnotationMethodsFacetFactory;
-import org.apache.isis.core.metamodel.facets.object.ignore.isis.RemoveSetDomainObjectContainerMethodFacetFactory;
-import org.apache.isis.core.metamodel.facets.object.ignore.isis.RemoveStaticGettersAndSettersFacetFactory;
-import org.apache.isis.core.metamodel.facets.object.ignore.jdo.RemoveJdoEnhancementTypesFacetFactory;
-import org.apache.isis.core.metamodel.facets.object.ignore.jdo.RemoveJdoPrefixedMethodsFacetFactory;
-import org.apache.isis.core.metamodel.facets.object.membergroups.annotprop.MemberGroupLayoutFacetFactory;
-import org.apache.isis.core.metamodel.facets.object.plural.annotation.PluralAnnotationFacetFactory;
-import org.apache.isis.core.metamodel.facets.object.title.annotation.TitleAnnotationFacetFactory;
-import org.apache.isis.core.metamodel.facets.object.validating.mustsatisfyspec.MustSatisfySpecificationOnTypeFacetFactory;
-import org.apache.isis.core.metamodel.facets.param.validating.mustsatisfyspec.MustSatisfySpecificationOnParameterFacetFactory;
-import org.apache.isis.core.metamodel.facets.properties.update.PropertyModifyFacetFactory;
-import org.apache.isis.core.metamodel.facets.properties.update.PropertySetAndClearFacetFactory;
-import org.apache.isis.core.metamodel.facets.properties.multiline.annotation.MultiLineOnPropertyFacetFactory;
-import org.apache.isis.core.metamodel.facets.properties.renderedasdaybefore.annotation.RenderedAsDayBeforeAnnotationOnPropertyFacetFactory;
-import org.apache.isis.core.metamodel.facets.properties.typicallen.annotation.TypicalLengthOnPropertyFacetFactory;
+import org.apache.isis.core.metamodel.facets.properties.validating.method.PropertyValidateFacetViaMethodFactory;
 import org.apache.isis.core.metamodel.facets.properties.validating.mustsatisfyspec.MustSatisfySpecificationOnPropertyFacetFactory;
+import org.apache.isis.core.metamodel.facets.properties.validating.regexannot.RegExFacetFacetOnPropertyAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.value.bigdecimal.BigDecimalValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.biginteger.BigIntegerValueFacetUsingSemanticsProviderFactory;
+import org.apache.isis.core.metamodel.facets.value.blobs.BlobValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.booleans.BooleanPrimitiveValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.booleans.BooleanWrapperValueFacetUsingSemanticsProviderFactory;
+import org.apache.isis.core.metamodel.facets.value.bytes.BytePrimitiveValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.bytes.ByteWrapperValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.chars.CharPrimitiveValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.chars.CharWrapperValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.clobs.ClobValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.color.ColorValueFacetUsingSemanticsProviderFactory;
+import org.apache.isis.core.metamodel.facets.value.date.DateValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.datejodalocal.JodaLocalDateValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.datesql.JavaSqlDateValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.datetime.DateTimeValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.datetimejoda.JodaDateTimeValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.datetimejodalocal.JodaLocalDateTimeValueFacetUsingSemanticsProviderFactory;
+import org.apache.isis.core.metamodel.facets.value.dateutil.JavaUtilDateValueFacetUsingSemanticsProviderFactory;
+import org.apache.isis.core.metamodel.facets.value.doubles.DoublePrimitiveValueFacetUsingSemanticsProviderFactory;
+import org.apache.isis.core.metamodel.facets.value.doubles.DoubleWrapperValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.floats.FloatPrimitiveValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.floats.FloatWrapperValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.image.ImageValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.imageawt.JavaAwtImageValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.integer.IntPrimitiveValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.integer.IntWrapperValueFacetUsingSemanticsProviderFactory;
-import org.apache.isis.core.metamodel.facets.value.doubles.DoubleWrapperValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.longs.LongPrimitiveValueFacetUsingSemanticsProviderFactory;
+import org.apache.isis.core.metamodel.facets.value.longs.LongWrapperValueFacetUsingSemanticsProviderFactory;
+import org.apache.isis.core.metamodel.facets.value.money.MoneyValueFacetUsingSemanticsProviderFactory;
+import org.apache.isis.core.metamodel.facets.value.password.PasswordValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.percentage.PercentageValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.shortint.ShortPrimitiveValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.shortint.ShortWrapperValueFacetUsingSemanticsProviderFactory;
@@ -208,8 +207,10 @@ import org.apache.isis.core.metamodel.facets.value.string.StringValueFacetUsingS
 import org.apache.isis.core.metamodel.facets.value.time.TimeValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.timesql.JavaSqlTimeValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.timestamp.TimeStampValueFacetUsingSemanticsProviderFactory;
+import org.apache.isis.core.metamodel.facets.value.timestampsql.JavaSqlTimeStampValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.url.URLValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.uuid.UUIDValueFacetUsingSemanticsProviderFactory;
+import org.apache.isis.core.metamodel.progmodel.ProgrammingModelAbstract;
 
 public final class ProgrammingModelFacetsJava5 extends ProgrammingModelAbstract {
 
@@ -367,6 +368,7 @@ public final class ProgrammingModelFacetsJava5 extends ProgrammingModelAbstract
 
         addFactory(ImmutableFacetMarkerInterfaceFactory.class);
 
+        addFactory(ViewModelFacetAnnotationFactory.class);
         addFactory(ViewModelFacetInterfaceFactory.class);
 
         addFactory(MaxLengthFacetOnTypeAnnotationFactory.class);

http://git-wip-us.apache.org/repos/asf/isis/blob/c88a590e/core/objectstore-jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/spi/DataNucleusIdentifierGenerator.java
----------------------------------------------------------------------
diff --git a/core/objectstore-jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/spi/DataNucleusIdentifierGenerator.java b/core/objectstore-jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/spi/DataNucleusIdentifierGenerator.java
index f1fc002..d3cd960 100644
--- a/core/objectstore-jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/spi/DataNucleusIdentifierGenerator.java
+++ b/core/objectstore-jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/spi/DataNucleusIdentifierGenerator.java
@@ -30,7 +30,10 @@ import org.apache.isis.applib.ViewModel;
 import org.apache.isis.core.commons.debug.DebugBuilder;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
 import org.apache.isis.core.metamodel.spec.ObjectSpecId;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.SpecificationLoader;
 import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.core.runtime.system.persistence.IdentifierGenerator;
 import org.apache.isis.objectstore.jdo.datanucleus.DataNucleusObjectStore;
@@ -46,12 +49,16 @@ public class DataNucleusIdentifierGenerator implements IdentifierGenerator {
     // main api
     // //////////////////////////////////////////////////////////////
 
+    /**
+     * TODO: this is really to create a transient or view model identifier.  The responsibilities are split unhappily between this class and its caller, the OidGenerator.
+     */
     @Override
     public String createTransientIdentifierFor(ObjectSpecId objectSpecId, Object pojo) {
-        
-        if(pojo instanceof ViewModel) {
-            ViewModel viewModel = (ViewModel) pojo;
-            return viewModel.viewModelMemento();
+
+        final ObjectSpecification spec = getSpecificationLoader().lookupBySpecId(objectSpecId);
+        final ViewModelFacet viewModelFacet = spec.getFacet(ViewModelFacet.class);
+        if(viewModelFacet != null) {
+            return viewModelFacet.memento(pojo);
         }
 
         return UUID.randomUUID().toString();
@@ -112,6 +119,9 @@ public class DataNucleusIdentifierGenerator implements IdentifierGenerator {
     protected DataNucleusObjectStore getDataNucleusObjectStore() {
         return (DataNucleusObjectStore) IsisContext.getPersistenceSession().getObjectStore();
     }
+    protected SpecificationLoader getSpecificationLoader() {
+        return IsisContext.getSpecificationLoader();
+    }
 
 }
 // Copyright (c) Naked Objects Group Ltd.

http://git-wip-us.apache.org/repos/asf/isis/blob/c88a590e/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/internal/RuntimeContextFromSession.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/internal/RuntimeContextFromSession.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/internal/RuntimeContextFromSession.java
index 09437cc..391802d 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/internal/RuntimeContextFromSession.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/internal/RuntimeContextFromSession.java
@@ -20,7 +20,6 @@
 package org.apache.isis.core.runtime.persistence.internal;
 
 import java.util.List;
-
 import org.apache.isis.applib.RecoverableException;
 import org.apache.isis.applib.profiles.Localization;
 import org.apache.isis.applib.query.Query;
@@ -28,18 +27,7 @@ import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
 import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
 import org.apache.isis.core.commons.authentication.AuthenticationSessionProviderAbstract;
-import org.apache.isis.core.metamodel.adapter.DomainObjectServices;
-import org.apache.isis.core.metamodel.adapter.DomainObjectServicesAbstract;
-import org.apache.isis.core.metamodel.adapter.LocalizationProviderAbstract;
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.adapter.ObjectDirtier;
-import org.apache.isis.core.metamodel.adapter.ObjectDirtierAbstract;
-import org.apache.isis.core.metamodel.adapter.ObjectPersistor;
-import org.apache.isis.core.metamodel.adapter.ObjectPersistorAbstract;
-import org.apache.isis.core.metamodel.adapter.QuerySubmitter;
-import org.apache.isis.core.metamodel.adapter.QuerySubmitterAbstract;
-import org.apache.isis.core.metamodel.adapter.ServicesProvider;
-import org.apache.isis.core.metamodel.adapter.ServicesProviderAbstract;
+import org.apache.isis.core.metamodel.adapter.*;
 import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
 import org.apache.isis.core.metamodel.adapter.mgr.AdapterManagerAware;
 import org.apache.isis.core.metamodel.adapter.oid.Oid;
@@ -61,7 +49,6 @@ import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
 import org.apache.isis.core.runtime.system.session.IsisSession;
 import org.apache.isis.core.runtime.system.transaction.IsisTransaction;
-import org.apache.isis.core.runtime.system.transaction.IsisTransaction.State;
 import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
 import org.apache.isis.core.runtime.system.transaction.MessageBroker;
 import org.apache.isis.core.runtime.system.transaction.UpdateNotifier;
@@ -123,6 +110,16 @@ public class RuntimeContextFromSession extends RuntimeContextAbstract {
             }
 
             @Override
+            public ObjectAdapter mapRecreatedPojo(Oid oid, Object recreatedPojo) {
+                return getRuntimeAdapterManager().mapRecreatedPojo(oid, recreatedPojo);
+            }
+
+            @Override
+            public void removeAdapter(ObjectAdapter adapter) {
+                getRuntimeAdapterManager().removeAdapter(adapter);
+            }
+
+            @Override
             public ObjectAdapter adapterFor(TypedOid oid) {
             	return getRuntimeAdapterManager().adapterFor(oid);
             }
@@ -198,6 +195,11 @@ public class RuntimeContextFromSession extends RuntimeContextAbstract {
             }
 
             @Override
+            public ObjectAdapter existingViewModelInstance(final Object viewModelPojo) {
+                return getPersistenceSession().existingViewModelInstance(viewModelPojo);
+            }
+
+            @Override
             public ObjectAdapter createAggregatedInstance(final ObjectSpecification spec, final ObjectAdapter parent) {
                 return getPersistenceSession().createAggregatedInstance(spec, parent);
             };

http://git-wip-us.apache.org/repos/asf/isis/blob/c88a590e/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/AdapterManagerSpi.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/AdapterManagerSpi.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/AdapterManagerSpi.java
index 43cef7f..b5da1fc 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/AdapterManagerSpi.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/AdapterManagerSpi.java
@@ -77,5 +77,4 @@ public interface AdapterManagerSpi extends AdapterManager, Iterable<ObjectAdapte
      */
     void removeAdapter(ObjectAdapter adapter);
 
-
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/c88a590e/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/OidGenerator.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/OidGenerator.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/OidGenerator.java
index d5b8cb7..3b1255a 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/OidGenerator.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/OidGenerator.java
@@ -19,16 +19,11 @@
 
 package org.apache.isis.core.runtime.system.persistence;
 
-import org.apache.isis.applib.ViewModel;
 import org.apache.isis.applib.annotation.Aggregated;
 import org.apache.isis.core.commons.debug.DebugBuilder;
 import org.apache.isis.core.commons.debug.DebuggableWithTitle;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.adapter.oid.AggregatedOid;
-import org.apache.isis.core.metamodel.adapter.oid.Oid;
-import org.apache.isis.core.metamodel.adapter.oid.RootOid;
-import org.apache.isis.core.metamodel.adapter.oid.RootOidDefault;
-import org.apache.isis.core.metamodel.adapter.oid.TypedOid;
+import org.apache.isis.core.metamodel.adapter.oid.*;
 import org.apache.isis.core.metamodel.adapter.oid.Oid.State;
 import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
 import org.apache.isis.core.metamodel.spec.ObjectSpecId;
@@ -61,12 +56,14 @@ public class OidGenerator implements DebuggableWithTitle {
     /**
      * Create a new {@link Oid#isTransient() transient} {@link Oid} for the
      * supplied pojo, uniquely distinguishable from any other {@link Oid}.
+     *
+     * TODO: the responsibility for knowing if this pojo is a view model or not are split unhappily between this class and the {@link org.apache.isis.core.runtime.system.persistence.IdentifierGenerator} impl.
      */
     public final RootOid createTransientOrViewModelOid(final Object pojo) {
-        ObjectSpecification spec = getSpecificationLookup().loadSpecification(pojo.getClass());
+        final ObjectSpecification spec = getSpecificationLookup().loadSpecification(pojo.getClass());
         final ObjectSpecId objectSpecId = spec.getSpecId();
         final String transientIdentifier = identifierGenerator.createTransientIdentifierFor(objectSpecId, pojo);
-        final State state = spec.containsFacet(ViewModelFacet.class)? State.VIEWMODEL:State.TRANSIENT;
+        final State state = spec.containsDoOpFacet(ViewModelFacet.class)? State.VIEWMODEL:State.TRANSIENT;
         return new RootOidDefault(objectSpecId, transientIdentifier, state);
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/c88a590e/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
index 9af451c..3623f74 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
@@ -334,6 +334,21 @@ public class PersistenceSession implements Persistor, EnlistedObjectDirtying, To
         return objectSpec.initialize(adapter);
     }
 
+    public ObjectAdapter existingViewModelInstance(final Object viewModelPojo) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("existing view model instance of " + viewModelPojo);
+        }
+        final ObjectSpecification objectSpec = getSpecificationLoader().loadSpecification(viewModelPojo.getClass());
+        if(!objectSpec.containsDoOpFacet(ViewModelFacet.class)) {
+            throw new IllegalArgumentException("viewModelPojo " + viewModelPojo + " is not a view model (eg @ViewModel annotation or ViewModel interface)");
+        }
+        final ViewModelFacet facet = objectSpec.getFacet(ViewModelFacet.class);
+        final String memento = facet.memento(viewModelPojo);
+
+        final ObjectAdapter adapter = getAdapterManager().adapterFor(viewModelPojo);
+        return adapter;
+    }
+
     @Override
     public ObjectAdapter createAggregatedInstance(final ObjectSpecification objectSpec, final ObjectAdapter parentAdapter) {
         if (LOG.isDebugEnabled()) {

http://git-wip-us.apache.org/repos/asf/isis/blob/c88a590e/example/application/todoapp/dom/src/main/java/app/ToDoItemAnalysis.java
----------------------------------------------------------------------
diff --git a/example/application/todoapp/dom/src/main/java/app/ToDoItemAnalysis.java b/example/application/todoapp/dom/src/main/java/app/ToDoItemAnalysis.java
index ed7ffba..6ed2010 100644
--- a/example/application/todoapp/dom/src/main/java/app/ToDoItemAnalysis.java
+++ b/example/application/todoapp/dom/src/main/java/app/ToDoItemAnalysis.java
@@ -58,10 +58,7 @@ public class ToDoItemAnalysis {
         return new Function<Category, ToDoItemsByCategoryViewModel>(){
              @Override
              public ToDoItemsByCategoryViewModel apply(final Category category) {
-                 final ToDoItemsByCategoryViewModel byCategory = 
-                     container.newViewModelInstance(ToDoItemsByCategoryViewModel.class, category.name());
-                 byCategory.setCategory(category);
-                 return byCategory;
+                 return container.existingViewModelInstance(new ToDoItemsByCategoryViewModel(category));
              }
          };
     }
@@ -91,10 +88,7 @@ public class ToDoItemAnalysis {
         return new Function<DateRange, ToDoItemsByDateRangeViewModel>(){
              @Override
              public ToDoItemsByDateRangeViewModel apply(final DateRange dateRange) {
-                 final ToDoItemsByDateRangeViewModel byDateRange = 
-                     container.newViewModelInstance(ToDoItemsByDateRangeViewModel.class, dateRange.name());
-                 byDateRange.setDateRange(dateRange);
-                 return byDateRange;
+                 return container.existingViewModelInstance(new ToDoItemsByDateRangeViewModel(dateRange));
              }
          };
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/c88a590e/example/application/todoapp/dom/src/main/java/app/ToDoItemsByCategoryViewModel.java
----------------------------------------------------------------------
diff --git a/example/application/todoapp/dom/src/main/java/app/ToDoItemsByCategoryViewModel.java b/example/application/todoapp/dom/src/main/java/app/ToDoItemsByCategoryViewModel.java
index 53d6305..2129bb6 100644
--- a/example/application/todoapp/dom/src/main/java/app/ToDoItemsByCategoryViewModel.java
+++ b/example/application/todoapp/dom/src/main/java/app/ToDoItemsByCategoryViewModel.java
@@ -29,35 +29,29 @@ import com.google.common.base.Function;
 import com.google.common.base.Joiner;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
-import org.apache.isis.applib.AbstractViewModel;
+import org.apache.isis.applib.DomainObjectContainer;
 import org.apache.isis.applib.annotation.*;
 import org.apache.isis.applib.annotation.Render.Type;
 import org.apache.isis.applib.util.ObjectContracts;
 
 @Named("By Category")
 @Bookmarkable
+@ViewModel
 public class ToDoItemsByCategoryViewModel 
-        extends AbstractViewModel 
         implements Comparable<ToDoItemsByCategoryViewModel> {
 
-    //region > viewModel implementation
-    @Override
-    public String viewModelMemento() {
-        return getCategory().name();
+    //region > constructors
+    public ToDoItemsByCategoryViewModel() {
     }
-
-    @Override
-    public void viewModelInit(String memento) {
-        setCategory(Category.valueOf(memento));
+    public ToDoItemsByCategoryViewModel(Category category) {
+        setCategory(category);
     }
     //endregion
 
+
     //region > category (property)
     private Category category;
 
-    /**
-     * Used as {@link #viewModelMemento() memento}
-     */
     @Title
     public Category getCategory() {
         return category;
@@ -129,7 +123,7 @@ public class ToDoItemsByCategoryViewModel
     @Named("Delete")
     public ToDoItemsByCategoryViewModel deleteCompleted() {
         for (ToDoItem item : getItemsComplete()) {
-            removeIfNotAlready(item);
+            container.removeIfNotAlready(item);
         }
         // force reload of page
         return this;
@@ -146,6 +140,8 @@ public class ToDoItemsByCategoryViewModel
 
     //region > injected services
     @javax.inject.Inject
+    private DomainObjectContainer container;
+    @javax.inject.Inject
     private ToDoItems toDoItems;
     //endregion
 

http://git-wip-us.apache.org/repos/asf/isis/blob/c88a590e/example/application/todoapp/dom/src/main/java/app/ToDoItemsByDateRangeViewModel.java
----------------------------------------------------------------------
diff --git a/example/application/todoapp/dom/src/main/java/app/ToDoItemsByDateRangeViewModel.java b/example/application/todoapp/dom/src/main/java/app/ToDoItemsByDateRangeViewModel.java
index ba5d20d..4768e14 100644
--- a/example/application/todoapp/dom/src/main/java/app/ToDoItemsByDateRangeViewModel.java
+++ b/example/application/todoapp/dom/src/main/java/app/ToDoItemsByDateRangeViewModel.java
@@ -33,39 +33,28 @@ import dom.todo.ToDoItems;
 import org.joda.time.DateTime;
 
 import org.apache.isis.applib.AbstractViewModel;
-import org.apache.isis.applib.annotation.Bookmarkable;
-import org.apache.isis.applib.annotation.Named;
-import org.apache.isis.applib.annotation.Render;
+import org.apache.isis.applib.annotation.*;
 import org.apache.isis.applib.annotation.Render.Type;
-import org.apache.isis.applib.annotation.Title;
 import org.apache.isis.applib.services.clock.ClockService;
 import org.apache.isis.applib.util.ObjectContracts;
 
 @Named("By Date Range")
 @Bookmarkable
-public class ToDoItemsByDateRangeViewModel 
-        extends AbstractViewModel 
+@ViewModel
+public class ToDoItemsByDateRangeViewModel
         implements Comparable<ToDoItemsByDateRangeViewModel> {
 
-    //region > viewModel implementation
-    @Override
-    public String viewModelMemento() {
-        return getDateRange().name();
+    //region > constructors
+    public ToDoItemsByDateRangeViewModel() {
     }
-
-    @Override
-    public void viewModelInit(String memento) {
-        setDateRange(DateRange.valueOf(memento));
+    public ToDoItemsByDateRangeViewModel(DateRange dateRange) {
+        setDateRange(dateRange);
     }
-
     //endregion
 
     //region > dateRange (property)
     private DateRange dateRange;
 
-    /**
-     * Used as {@link #viewModelMemento() memento}
-     */
     @Title
     public DateRange getDateRange() {
         return dateRange;


[2/2] git commit: ISIS-809: removed DOC#existingViewModelInstance (not required); ViewModel facet implies disabled property and collection (unless implements ViewModel.Cloneable); reworked FixtureResult to take advantage of @ViewModel.

Posted by da...@apache.org.
ISIS-809: removed DOC#existingViewModelInstance (not required); ViewModel facet implies disabled property and collection (unless implements ViewModel.Cloneable); reworked FixtureResult to take advantage of @ViewModel.


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

Branch: refs/heads/master
Commit: fa1876c02bce7225f0315406c73b3f6f2a15ed3f
Parents: c88a590
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Wed Sep 24 19:20:45 2014 +0100
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Wed Sep 24 19:20:45 2014 +0100

----------------------------------------------------------------------
 .../isis/applib/AbstractContainedObject.java    |  3 +-
 .../apache/isis/applib/AbstractViewModel.java   | 26 +++--------
 .../isis/applib/DomainObjectContainer.java      | 11 +++--
 .../applib/fixturescripts/FixtureResult.java    | 15 +-----
 .../applib/fixturescripts/FixtureScripts.java   | 46 +++----------------
 .../metamodel/adapter/DomainObjectServices.java |  2 -
 .../core/metamodel/facetapi/FeatureType.java    |  1 +
 ...edFacetOnCollectionDerivedFromViewModel.java | 41 +++++++++++++++++
 ...lectionDerivedFromViewModelFacetFactory.java | 48 ++++++++++++++++++++
 ...bledFacetOnPropertyDerivedFromViewModel.java | 41 +++++++++++++++++
 ...ropertyDerivedFromViewModelFacetFactory.java | 48 ++++++++++++++++++++
 .../viewmodel/ViewModelFacetAbstract.java       | 13 ++++++
 .../annotation/ViewModelFacetAnnotation.java    | 13 +-----
 .../iface/ViewModelFacetInterface.java          | 11 -----
 .../noruntime/RuntimeContextNoRuntime.java      |  5 --
 .../container/DomainObjectContainerDefault.java | 20 --------
 .../dflt/ProgrammingModelFacetsJava5.java       |  4 ++
 .../internal/RuntimeContextFromSession.java     |  5 --
 .../services/memento/MementoServiceDefault.java |  9 +++-
 .../system/persistence/PersistenceSession.java  | 15 ------
 .../dom/src/main/java/app/ToDoItemAnalysis.java |  4 +-
 .../prototyping/ExternalLinksService.java       |  2 +-
 22 files changed, 230 insertions(+), 153 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/fa1876c0/core/applib/src/main/java/org/apache/isis/applib/AbstractContainedObject.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/AbstractContainedObject.java b/core/applib/src/main/java/org/apache/isis/applib/AbstractContainedObject.java
index d3f376c..9119117 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/AbstractContainedObject.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/AbstractContainedObject.java
@@ -67,7 +67,6 @@ public abstract class AbstractContainedObject {
      * {@link #newAggregatedInstance(Object, Class)}.  Otherwise will be an
      * aggregate root.
      * 
-     * @see #newPersistentInstance(Class)
      * @see #newAggregatedInstance(Object, Class)
      */
     @Hidden
@@ -169,7 +168,7 @@ public abstract class AbstractContainedObject {
     /**
      * Convenience method that delegates to {@link DomainObjectContainer}.
      * 
-     * @see DomainObjectContainer#allMatches(Query, long...)
+     * @see DomainObjectContainer#allMatches(Query)
      */
     protected <T> List<T> allMatches(final Query<T> query) {
         return getContainer().allMatches(query);

http://git-wip-us.apache.org/repos/asf/isis/blob/fa1876c0/core/applib/src/main/java/org/apache/isis/applib/AbstractViewModel.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/AbstractViewModel.java b/core/applib/src/main/java/org/apache/isis/applib/AbstractViewModel.java
index 64fb7c6..d1117f9 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/AbstractViewModel.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/AbstractViewModel.java
@@ -19,16 +19,18 @@
 
 package org.apache.isis.applib;
 
-import org.apache.isis.applib.annotation.Disabled;
-
 /**
- * Convenience super class for all view models that wish to interact with the
+ * Convenience super class for view models that wish to interact with the
  * container.
  * 
  * <p>
  * Subclassing is NOT mandatory; the methods in this superclass can be pushed
  * down into domain objects and another superclass used if required.
- * 
+ *
+ * <p>
+ *     As an alternative, consider simply annotating the view model class with {@link org.apache.isis.applib.annotation.ViewModel}.
+ * </p>
+ *
  * @see org.apache.isis.applib.DomainObjectContainer
  */
 public abstract class AbstractViewModel extends AbstractContainedObject implements ViewModel {
@@ -39,19 +41,5 @@ public abstract class AbstractViewModel extends AbstractContainedObject implemen
     @Override
     public abstract void viewModelInit(final String memento);
     
-    /**
-     * Equivalent to annotating every property and collection with {@link Disabled}.
-     */
-    public String disabled(Identifier.Type type) {
-        // cloneable view models are not read-only
-        // because the viewer can simulate them being edited
-        if(this instanceof ViewModel.Cloneable) {
-            return null;
-        }
-        if (type != Identifier.Type.PROPERTY_OR_COLLECTION) {
-            return null;
-        }
-        return "Non-cloneable view models are read-only";
-    }
-
 }
+

http://git-wip-us.apache.org/repos/asf/isis/blob/fa1876c0/core/applib/src/main/java/org/apache/isis/applib/DomainObjectContainer.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/DomainObjectContainer.java b/core/applib/src/main/java/org/apache/isis/applib/DomainObjectContainer.java
index 61aa27f..8972a66 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/DomainObjectContainer.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/DomainObjectContainer.java
@@ -166,15 +166,16 @@ public interface DomainObjectContainer {
     /**
      * Create a new instance of the specified {@link ViewModel} class, initializing with the
      * specified {@link ViewModel#viewModelMemento() memento}.
+     *
+     * <p>
+     *     Rather than use this constructor it is generally preferable to simply instantiate a
+     *     class annotated with {@link org.apache.isis.applib.annotation.ViewModel annotation}.
+     *     If services need injecting into it, use {@link #injectServicesInto(Object)}.
+     * </p>
      */
     <T extends ViewModel> T newViewModelInstance(final Class<T> ofType, final String memento);
 
     /**
-     * Recognizes/registers an existing object as a view model.
-     */
-    <T> T existingViewModelInstance(final T viewModelInstance);
-
-    /**
      * Create a new instance that will be persisted as part of the specified
      * parent (ie will be a part of a larger aggregate).
      * 

http://git-wip-us.apache.org/repos/asf/isis/blob/fa1876c0/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/FixtureResult.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/FixtureResult.java b/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/FixtureResult.java
index 8fa2056..55092fc 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/FixtureResult.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/FixtureResult.java
@@ -18,23 +18,12 @@
  */
 package org.apache.isis.applib.fixturescripts;
 
-import org.apache.isis.applib.AbstractViewModel;
 import org.apache.isis.applib.annotation.*;
 
+@ViewModel
 @Paged(500)
-public class FixtureResult extends AbstractViewModel {
+public class FixtureResult {
 
-    @Override
-    public String viewModelMemento() {
-        return fixtureScripts.mementoFor(this);
-    }
-    
-    @Override
-    public void viewModelInit(String memento) {
-        fixtureScripts.initOf(memento, this);
-    }
-
-    // //////////////////////////////////////
 
     private String fixtureScriptClassName;
 

http://git-wip-us.apache.org/repos/asf/isis/blob/fa1876c0/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/FixtureScripts.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/FixtureScripts.java b/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/FixtureScripts.java
index 03aa26b..4677734 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/FixtureScripts.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/FixtureScripts.java
@@ -23,24 +23,13 @@ import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Set;
-
 import javax.annotation.PostConstruct;
-
 import com.google.common.base.Predicate;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.Lists;
-
 import org.apache.isis.applib.AbstractService;
 import org.apache.isis.applib.ViewModel;
-import org.apache.isis.applib.annotation.DescribedAs;
-import org.apache.isis.applib.annotation.MemberOrder;
-import org.apache.isis.applib.annotation.MinLength;
-import org.apache.isis.applib.annotation.MultiLine;
-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.Prototype;
-import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.applib.annotation.*;
 import org.apache.isis.applib.services.bookmark.BookmarkService;
 import org.apache.isis.applib.services.classdiscovery.ClassDiscoveryService;
 import org.apache.isis.applib.services.memento.MementoService;
@@ -219,20 +208,6 @@ public abstract class FixtureScripts extends AbstractService {
 
     // //////////////////////////////////////
 
-    String mementoFor(FixtureResult fr) {
-        return mementoService.create()
-                .set("fixtureScriptClassName", fr.getFixtureScriptClassName())
-                .set("key", fr.getKey())
-                .set("object", bookmarkService.bookmarkFor(fr.getObject()))
-                .asString();
-    }
-    void initOf(String mementoStr, FixtureResult fr) {
-        Memento memento = mementoService.parse(mementoStr);
-        fr.setFixtureScriptClassName(memento.get("fixtureScriptClassName", String.class));
-        fr.setKey(memento.get("key", String.class));
-        fr.setObject(bookmarkService.lookup(memento.get("object", Bookmark.class)));
-    }
-
     FixtureResult newFixtureResult(FixtureScript script, String subkey, Object object, boolean firstTime) {
         if(object == null) {
             return null;
@@ -248,20 +223,11 @@ public abstract class FixtureScripts extends AbstractService {
                     return null;
             }
         }
-        String mementoFor = mementoFor(script, subkey, object, firstTime);
-        return getContainer().newViewModelInstance(FixtureResult.class, mementoFor);
-    }
-
-    private String mementoFor(
-            final FixtureScript script,
-            final String subkey,
-            final Object object,
-            final boolean firstTime) {
-        final FixtureResult template = new FixtureResult();
-        template.setFixtureScriptClassName(firstTime? script.getClass().getName(): null);
-        template.setKey(script.pathWith(subkey));
-        template.setObject(object);
-        return mementoFor(template);
+        final FixtureResult fixtureResult = new FixtureResult();
+        fixtureResult.setFixtureScriptClassName(firstTime ? script.getClass().getName() : null);
+        fixtureResult.setKey(script.pathWith(subkey));
+        fixtureResult.setObject(object);
+        return fixtureResult;
     }
 
     // //////////////////////////////////////

http://git-wip-us.apache.org/repos/asf/isis/blob/fa1876c0/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/DomainObjectServices.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/DomainObjectServices.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/DomainObjectServices.java
index ff30bc8..f559c4c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/DomainObjectServices.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/DomainObjectServices.java
@@ -42,8 +42,6 @@ public interface DomainObjectServices extends Injectable {
 
     ObjectAdapter createViewModelInstance(ObjectSpecification spec, String memento);
 
-    ObjectAdapter existingViewModelInstance(Object viewModelPojo);
-
     /**
      * Create an instance of an aggregated object that will be persisted within the
      * parent adapter.

http://git-wip-us.apache.org/repos/asf/isis/blob/fa1876c0/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FeatureType.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FeatureType.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FeatureType.java
index 18edf60..b78f7da 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FeatureType.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FeatureType.java
@@ -103,6 +103,7 @@ public enum FeatureType {
     public final static List<FeatureType> OBJECTS_ONLY = ImmutableList.of(OBJECT);
     public final static List<FeatureType> MEMBERS = ImmutableList.of(PROPERTY, COLLECTION, ACTION);
     public final static List<FeatureType> OBJECTS_AND_PROPERTIES = ImmutableList.of(OBJECT, PROPERTY);
+    public final static List<FeatureType> PROPERTIES_AND_COLLECTIONS = ImmutableList.of(PROPERTY, COLLECTION);
     public final static List<FeatureType> OBJECTS_AND_COLLECTIONS = ImmutableList.of(OBJECT, COLLECTION);
     public final static List<FeatureType> OBJECTS_AND_ACTIONS = ImmutableList.of(OBJECT, ACTION);
     public final static List<FeatureType> OBJECTS_PROPERTIES_AND_COLLECTIONS = ImmutableList.of(OBJECT, PROPERTY, COLLECTION);

http://git-wip-us.apache.org/repos/asf/isis/blob/fa1876c0/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/DisabledFacetOnCollectionDerivedFromViewModel.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/DisabledFacetOnCollectionDerivedFromViewModel.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/DisabledFacetOnCollectionDerivedFromViewModel.java
new file mode 100644
index 0000000..0c65e9d
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/DisabledFacetOnCollectionDerivedFromViewModel.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.core.metamodel.facets.object.viewmodel;
+
+import org.apache.isis.applib.annotation.When;
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.members.disabled.DisabledFacetAbstract;
+
+public class DisabledFacetOnCollectionDerivedFromViewModel extends DisabledFacetAbstract {
+
+    public DisabledFacetOnCollectionDerivedFromViewModel(final FacetHolder holder) {
+        super(When.ALWAYS, Where.ANYWHERE, holder);
+    }
+
+    @Override
+    public String disabledReason(final ObjectAdapter target) {
+        final ViewModelFacet facet = target.getSpecification().getFacet(ViewModelFacet.class);
+        final boolean cloneable = facet.isCloneable(target.getObject());
+        return !cloneable ? "Non-cloneable view models are read-only" : null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/fa1876c0/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/DisabledFacetOnCollectionDerivedFromViewModelFacetFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/DisabledFacetOnCollectionDerivedFromViewModelFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/DisabledFacetOnCollectionDerivedFromViewModelFacetFactory.java
new file mode 100644
index 0000000..175e3ec
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/DisabledFacetOnCollectionDerivedFromViewModelFacetFactory.java
@@ -0,0 +1,48 @@
+/*
+ *  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.viewmodel;
+
+import java.lang.reflect.Method;
+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.FacetedMethod;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+
+public class DisabledFacetOnCollectionDerivedFromViewModelFacetFactory extends FacetFactoryAbstract {
+
+    public DisabledFacetOnCollectionDerivedFromViewModelFacetFactory() {
+        super(FeatureType.COLLECTIONS_ONLY);
+    }
+
+    @Override
+    public void process(final ProcessMethodContext processMethodContext) {
+        final Method method = processMethodContext.getMethod();
+        final Class<?> declaringClass = method.getDeclaringClass();
+        final ObjectSpecification spec = getSpecificationLoader().loadSpecification(declaringClass);
+
+        if (!spec.containsDoOpFacet(ViewModelFacet.class)) {
+            return;
+        }
+        final FacetedMethod facetHolder = processMethodContext.getFacetHolder();
+        FacetUtil.addFacet(new DisabledFacetOnCollectionDerivedFromViewModel(facetHolder));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/fa1876c0/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/DisabledFacetOnPropertyDerivedFromViewModel.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/DisabledFacetOnPropertyDerivedFromViewModel.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/DisabledFacetOnPropertyDerivedFromViewModel.java
new file mode 100644
index 0000000..0e2fcbe
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/DisabledFacetOnPropertyDerivedFromViewModel.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.core.metamodel.facets.object.viewmodel;
+
+import org.apache.isis.applib.annotation.When;
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.members.disabled.DisabledFacetAbstract;
+
+public class DisabledFacetOnPropertyDerivedFromViewModel extends DisabledFacetAbstract {
+
+    public DisabledFacetOnPropertyDerivedFromViewModel(final FacetHolder holder) {
+        super(When.ALWAYS, Where.ANYWHERE, holder);
+    }
+
+    @Override
+    public String disabledReason(final ObjectAdapter target) {
+        final ViewModelFacet facet = target.getSpecification().getFacet(ViewModelFacet.class);
+        final boolean cloneable = facet.isCloneable(target.getObject());
+        return !cloneable ? "Non-cloneable view models are read-only" : null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/fa1876c0/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/DisabledFacetOnPropertyDerivedFromViewModelFacetFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/DisabledFacetOnPropertyDerivedFromViewModelFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/DisabledFacetOnPropertyDerivedFromViewModelFacetFactory.java
new file mode 100644
index 0000000..1020f01
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/DisabledFacetOnPropertyDerivedFromViewModelFacetFactory.java
@@ -0,0 +1,48 @@
+/*
+ *  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.viewmodel;
+
+import java.lang.reflect.Method;
+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.FacetedMethod;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+
+public class DisabledFacetOnPropertyDerivedFromViewModelFacetFactory extends FacetFactoryAbstract {
+
+    public DisabledFacetOnPropertyDerivedFromViewModelFacetFactory() {
+        super(FeatureType.PROPERTIES_ONLY);
+    }
+
+    @Override
+    public void process(final ProcessMethodContext processMethodContext) {
+        final Method method = processMethodContext.getMethod();
+        final Class<?> declaringClass = method.getDeclaringClass();
+        final ObjectSpecification spec = getSpecificationLoader().loadSpecification(declaringClass);
+
+        if (!spec.containsDoOpFacet(ViewModelFacet.class)) {
+            return;
+        }
+        final FacetedMethod facetHolder = processMethodContext.getFacetHolder();
+        FacetUtil.addFacet(new DisabledFacetOnPropertyDerivedFromViewModel(facetHolder));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/fa1876c0/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/ViewModelFacetAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/ViewModelFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/ViewModelFacetAbstract.java
index 63a604c..5d20559 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/ViewModelFacetAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/ViewModelFacetAbstract.java
@@ -19,6 +19,7 @@
 
 package org.apache.isis.core.metamodel.facets.object.viewmodel;
 
+import org.apache.isis.applib.ViewModel;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.MarkerFacetAbstract;
@@ -33,4 +34,16 @@ public abstract class ViewModelFacetAbstract extends MarkerFacetAbstract impleme
         super(type(), holder);
     }
 
+    @Override
+    public boolean isCloneable(Object pojo) {
+        return pojo != null && pojo instanceof ViewModel.Cloneable;
+    }
+
+    @Override
+    public Object clone(Object pojo) {
+        ViewModel.Cloneable viewModelCloneable = (ViewModel.Cloneable) pojo;
+        return viewModelCloneable.clone();
+    }
+
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/fa1876c0/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/annotation/ViewModelFacetAnnotation.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/annotation/ViewModelFacetAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/annotation/ViewModelFacetAnnotation.java
index ba21e2b..0b5d11e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/annotation/ViewModelFacetAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/annotation/ViewModelFacetAnnotation.java
@@ -86,7 +86,7 @@ public class ViewModelFacetAnnotation extends ViewModelFacetAbstract {
                 final Class<?> propertyType = property.getSpecification().getCorrespondingClass();
                 propertyValue = memento.get(propertyId, propertyType);
             } else if(mementoKeys.contains(propertyId + ".bookmark")) {
-                final Bookmark propertyValueBookmark = memento.get(propertyId, Bookmark.class);
+                final Bookmark propertyValueBookmark = memento.get(propertyId + ".bookmark", Bookmark.class);
                 propertyValue = bookmarkService.lookup(propertyValueBookmark);
             }
 
@@ -152,16 +152,5 @@ public class ViewModelFacetAnnotation extends ViewModelFacetAbstract {
         }
     }
 
-    @Override
-    public boolean isCloneable(Object pojo) {
-        return pojo != null && pojo instanceof ViewModel.Cloneable;
-    }
-
-    @Override
-    public Object clone(Object pojo) {
-        ViewModel.Cloneable viewModelCloneable = (ViewModel.Cloneable) pojo;
-        return viewModelCloneable.clone();
-    }
-
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/fa1876c0/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/iface/ViewModelFacetInterface.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/iface/ViewModelFacetInterface.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/iface/ViewModelFacetInterface.java
index cf48b0e..6c68898 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/iface/ViewModelFacetInterface.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/iface/ViewModelFacetInterface.java
@@ -41,15 +41,4 @@ public class ViewModelFacetInterface extends ViewModelFacetAbstract {
         return viewModel.viewModelMemento();
     }
 
-    @Override
-    public boolean isCloneable(Object pojo) {
-        return pojo != null && pojo instanceof ViewModel.Cloneable;
-    }
-
-    @Override
-    public Object clone(Object pojo) {
-        ViewModel.Cloneable viewModelCloneable = (ViewModel.Cloneable) pojo;
-        return viewModelCloneable.clone();
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/fa1876c0/core/metamodel/src/main/java/org/apache/isis/core/metamodel/runtimecontext/noruntime/RuntimeContextNoRuntime.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/runtimecontext/noruntime/RuntimeContextNoRuntime.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/runtimecontext/noruntime/RuntimeContextNoRuntime.java
index c2d5a06..30363b5 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/runtimecontext/noruntime/RuntimeContextNoRuntime.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/runtimecontext/noruntime/RuntimeContextNoRuntime.java
@@ -203,11 +203,6 @@ public class RuntimeContextNoRuntime extends RuntimeContextAbstract {
             }
 
             @Override
-            public ObjectAdapter existingViewModelInstance(Object viewModelPojo) {
-                throw new UnsupportedOperationException("Not supported by this implementation of RuntimeContext");
-            }
-
-            @Override
             public ObjectAdapter createAggregatedInstance(final ObjectSpecification spec, final ObjectAdapter parent) {
                 throw new UnsupportedOperationException("Not supported by this implementation of RuntimeContext");
             }

http://git-wip-us.apache.org/repos/asf/isis/blob/fa1876c0/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/container/DomainObjectContainerDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/container/DomainObjectContainerDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/container/DomainObjectContainerDefault.java
index cc73282..e6c4f7c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/container/DomainObjectContainerDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/container/DomainObjectContainerDefault.java
@@ -113,22 +113,6 @@ public class  DomainObjectContainerDefault implements DomainObjectContainer, Que
         }
     }
 
-    @SuppressWarnings("unchecked")
-    @Override
-    public <T> T existingViewModelInstance(final T viewModelPojo) {
-        final Class<?> viewModelClass = viewModelPojo.getClass();
-        final ObjectSpecification spec = getSpecificationLookup().loadSpecification(viewModelClass);
-        if (!spec.containsFacet(ViewModelFacet.class)) {
-            throw new IsisException("Type must be a ViewModel: " + viewModelClass);
-        }
-        final ObjectAdapter adapter = doExistingViewModelInstance(viewModelPojo);
-        if(adapter.getOid().isViewModel()) {
-            return (T)adapter.getObject();
-        } else {
-            throw new IsisException("Object is not a ViewModel (imple,e");
-        }
-    }
-
     @Override
     @SuppressWarnings("unchecked")
     public <T> T newAggregatedInstance(final Object parent, final Class<T> ofClass) {
@@ -179,10 +163,6 @@ public class  DomainObjectContainerDefault implements DomainObjectContainer, Que
         return getDomainObjectServices().createViewModelInstance(spec, memento);
     }
 
-    protected ObjectAdapter doExistingViewModelInstance(final Object viewModelPojo) {
-        return getDomainObjectServices().existingViewModelInstance(viewModelPojo);
-    }
-
     private ObjectAdapter doCreateAggregatedInstance(final ObjectSpecification spec, final Object parent) {
         final ObjectAdapter parentAdapter = getAdapterManager().getAdapterFor(parent);
         return getDomainObjectServices().createAggregatedInstance(spec, parentAdapter);

http://git-wip-us.apache.org/repos/asf/isis/blob/fa1876c0/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java b/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
index 70bd53f..26acc45 100644
--- a/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
+++ b/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
@@ -123,6 +123,8 @@ import org.apache.isis.core.metamodel.facets.object.typicallen.annotation.Typica
 import org.apache.isis.core.metamodel.facets.object.validating.mustsatisfyspec.MustSatisfySpecificationOnTypeFacetFactory;
 import org.apache.isis.core.metamodel.facets.object.validating.validateobject.method.ValidateObjectFacetMethodFactory;
 import org.apache.isis.core.metamodel.facets.object.value.annotcfg.ValueFacetAnnotationOrConfigurationFactory;
+import org.apache.isis.core.metamodel.facets.object.viewmodel.DisabledFacetOnCollectionDerivedFromViewModelFacetFactory;
+import org.apache.isis.core.metamodel.facets.object.viewmodel.DisabledFacetOnPropertyDerivedFromViewModelFacetFactory;
 import org.apache.isis.core.metamodel.facets.object.viewmodel.annotation.ViewModelFacetAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.object.viewmodel.iface.ViewModelFacetInterfaceFactory;
 import org.apache.isis.core.metamodel.facets.param.autocomplete.method.ActionParameterAutoCompleteFacetViaMethodFactory;
@@ -370,6 +372,8 @@ public final class ProgrammingModelFacetsJava5 extends ProgrammingModelAbstract
 
         addFactory(ViewModelFacetAnnotationFactory.class);
         addFactory(ViewModelFacetInterfaceFactory.class);
+        addFactory(DisabledFacetOnPropertyDerivedFromViewModelFacetFactory.class);
+        addFactory(DisabledFacetOnCollectionDerivedFromViewModelFacetFactory.class);
 
         addFactory(MaxLengthFacetOnTypeAnnotationFactory.class);
         addFactory(MaxLengthFacetOnPropertyAnnotationFactory.class);

http://git-wip-us.apache.org/repos/asf/isis/blob/fa1876c0/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/internal/RuntimeContextFromSession.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/internal/RuntimeContextFromSession.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/internal/RuntimeContextFromSession.java
index 391802d..d7e388c 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/internal/RuntimeContextFromSession.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/internal/RuntimeContextFromSession.java
@@ -195,11 +195,6 @@ public class RuntimeContextFromSession extends RuntimeContextAbstract {
             }
 
             @Override
-            public ObjectAdapter existingViewModelInstance(final Object viewModelPojo) {
-                return getPersistenceSession().existingViewModelInstance(viewModelPojo);
-            }
-
-            @Override
             public ObjectAdapter createAggregatedInstance(final ObjectSpecification spec, final ObjectAdapter parent) {
                 return getPersistenceSession().createAggregatedInstance(spec, parent);
             };

http://git-wip-us.apache.org/repos/asf/isis/blob/fa1876c0/core/runtime/src/main/java/org/apache/isis/core/runtime/services/memento/MementoServiceDefault.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/memento/MementoServiceDefault.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/memento/MementoServiceDefault.java
index 06f955c..1975546 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/memento/MementoServiceDefault.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/memento/MementoServiceDefault.java
@@ -97,6 +97,14 @@ public class MementoServiceDefault implements MementoService {
             List<Element> elements = element.elements();
             return Sets.newLinkedHashSet(Iterables.transform(elements, ELEMENT_NAME));
         }
+
+        // //////////////////////////////////////
+
+        @Override
+        public String toString() {
+            return Dom4jUtil.asString(doc);
+        }
+
     }
 
     // //////////////////////////////////////
@@ -153,5 +161,4 @@ public class MementoServiceDefault implements MementoService {
         return BaseEncoding.base64Url().encode(bytes);
     }
 
-    
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/fa1876c0/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
index 3623f74..9af451c 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
@@ -334,21 +334,6 @@ public class PersistenceSession implements Persistor, EnlistedObjectDirtying, To
         return objectSpec.initialize(adapter);
     }
 
-    public ObjectAdapter existingViewModelInstance(final Object viewModelPojo) {
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("existing view model instance of " + viewModelPojo);
-        }
-        final ObjectSpecification objectSpec = getSpecificationLoader().loadSpecification(viewModelPojo.getClass());
-        if(!objectSpec.containsDoOpFacet(ViewModelFacet.class)) {
-            throw new IllegalArgumentException("viewModelPojo " + viewModelPojo + " is not a view model (eg @ViewModel annotation or ViewModel interface)");
-        }
-        final ViewModelFacet facet = objectSpec.getFacet(ViewModelFacet.class);
-        final String memento = facet.memento(viewModelPojo);
-
-        final ObjectAdapter adapter = getAdapterManager().adapterFor(viewModelPojo);
-        return adapter;
-    }
-
     @Override
     public ObjectAdapter createAggregatedInstance(final ObjectSpecification objectSpec, final ObjectAdapter parentAdapter) {
         if (LOG.isDebugEnabled()) {

http://git-wip-us.apache.org/repos/asf/isis/blob/fa1876c0/example/application/todoapp/dom/src/main/java/app/ToDoItemAnalysis.java
----------------------------------------------------------------------
diff --git a/example/application/todoapp/dom/src/main/java/app/ToDoItemAnalysis.java b/example/application/todoapp/dom/src/main/java/app/ToDoItemAnalysis.java
index 6ed2010..6149bb3 100644
--- a/example/application/todoapp/dom/src/main/java/app/ToDoItemAnalysis.java
+++ b/example/application/todoapp/dom/src/main/java/app/ToDoItemAnalysis.java
@@ -58,7 +58,7 @@ public class ToDoItemAnalysis {
         return new Function<Category, ToDoItemsByCategoryViewModel>(){
              @Override
              public ToDoItemsByCategoryViewModel apply(final Category category) {
-                 return container.existingViewModelInstance(new ToDoItemsByCategoryViewModel(category));
+                 return new ToDoItemsByCategoryViewModel(category);
              }
          };
     }
@@ -88,7 +88,7 @@ public class ToDoItemAnalysis {
         return new Function<DateRange, ToDoItemsByDateRangeViewModel>(){
              @Override
              public ToDoItemsByDateRangeViewModel apply(final DateRange dateRange) {
-                 return container.existingViewModelInstance(new ToDoItemsByDateRangeViewModel(dateRange));
+                 return new ToDoItemsByDateRangeViewModel(dateRange);
              }
          };
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/fa1876c0/example/application/todoapp/webapp/src/main/java/webapp/prototyping/ExternalLinksService.java
----------------------------------------------------------------------
diff --git a/example/application/todoapp/webapp/src/main/java/webapp/prototyping/ExternalLinksService.java b/example/application/todoapp/webapp/src/main/java/webapp/prototyping/ExternalLinksService.java
index 8d5d359..0606b0e 100644
--- a/example/application/todoapp/webapp/src/main/java/webapp/prototyping/ExternalLinksService.java
+++ b/example/application/todoapp/webapp/src/main/java/webapp/prototyping/ExternalLinksService.java
@@ -27,7 +27,7 @@ public class ExternalLinksService {
 
     public static enum ExternalLink {
         ISIS_DOCUMENTATION("Apache Isis docs", "http://isis.apache.org/documentation.html"),
-        PROJECT_ON_GITHUB("Project source code on Github", "https://github.com/apache/isis/tree/master/example/application/quickstart_wicket_restful_jdo/");
+        PROJECT_ON_GITHUB("Project source code on Github", "https://github.com/apache/isis/tree/master/example/application/todoapp/");
         
         private final String title;
         private final String url;