You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2013/10/11 19:04:01 UTC
git commit: ISIS-401: concurrency checking in bulk actions
Updated Branches:
refs/heads/master bda2045b3 -> b717f39f0
ISIS-401: concurrency checking in bulk actions
If user A and user B both check a row, then user A updates that row then
user B updates that row, then show warning to user B and refresh list.
In addition:
- renamed MyAjaxFallback* -> IsisAjaxFallback*
- moved some Functions and Matchers into nester static classes of Oid
and ObjectAdapterMemento
Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/b717f39f
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/b717f39f
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/b717f39f
Branch: refs/heads/master
Commit: b717f39f0f3f60e9f53a02378ee0cce3566ed88a
Parents: bda2045
Author: Dan Haywood <da...@apache.org>
Authored: Fri Oct 11 18:03:49 2013 +0100
Committer: Dan Haywood <da...@apache.org>
Committed: Fri Oct 11 18:03:49 2013 +0100
----------------------------------------------------------------------
.../wicket/model/common/SelectionHandler.java | 17 +--
.../model/mementos/ObjectAdapterMemento.java | 105 +++++++++++++++++++
.../model/models/EntityCollectionModel.java | 4 +-
.../wicket/model/util/MementoFunctions.java | 84 +++++++--------
.../model/util/ObjectAdapterFunctions.java | 32 +++---
.../viewer/wicket/model/util/OidMatchers.java | 40 +++----
.../ajaxtable/BulkActionsLinkFactory.java | 99 +++++++++++++----
.../CollectionContentsAsAjaxTablePanel.java | 36 ++++++-
.../ajaxtable/IsisAjaxFallbackDataTable.java | 53 ++++++++++
.../IsisAjaxFallbackHeadersToolbar.java | 73 +++++++++++++
.../MyAjaxFallbackDefaultDataTable.java | 53 ----------
.../ajaxtable/MyAjaxFallbackHeadersToolbar.java | 73 -------------
.../columns/ObjectAdapterToggleboxColumn.java | 21 +++-
.../entity/EntityActionLinkFactory.java | 12 ++-
.../isis/core/metamodel/adapter/oid/Oid.java | 42 ++++++++
15 files changed, 489 insertions(+), 255 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/isis/blob/b717f39f/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/common/SelectionHandler.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/common/SelectionHandler.java b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/common/SelectionHandler.java
index 3193fa8..dfecf23 100644
--- a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/common/SelectionHandler.java
+++ b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/common/SelectionHandler.java
@@ -22,20 +22,23 @@ package org.apache.isis.viewer.wicket.model.common;
import java.io.Serializable;
import org.apache.wicket.Component;
+import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.version.ConcurrencyException;
/**
* Decouples the mechanism for selecting entities returned in collections.
*/
public interface SelectionHandler extends Serializable {
- /**
- * The entity that has been selected.
- *
- * @param context
- * TODO
- */
- void onSelected(Component context, ObjectAdapter selectedAdapter);
+ void onSelected(
+ Component context, ObjectAdapter selectedAdapter,
+ AjaxRequestTarget ajaxRequestTarget);
+
+ void onConcurrencyException(
+ Component context, ObjectAdapter selectedAdapter,
+ ConcurrencyException ex,
+ AjaxRequestTarget ajaxRequestTarget);
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/b717f39f/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/ObjectAdapterMemento.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/ObjectAdapterMemento.java b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/ObjectAdapterMemento.java
index af0dc41..f7b4e0c 100644
--- a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/ObjectAdapterMemento.java
+++ b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/ObjectAdapterMemento.java
@@ -22,6 +22,8 @@ package org.apache.isis.viewer.wicket.model.mementos;
import java.io.Serializable;
import java.util.List;
+import com.google.common.base.Function;
+
import org.apache.isis.core.commons.ensure.Ensure;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
@@ -33,6 +35,10 @@ import org.apache.isis.core.metamodel.adapter.oid.TypedOid;
import org.apache.isis.core.metamodel.facets.object.encodeable.EncodableFacet;
import org.apache.isis.core.metamodel.spec.ObjectSpecId;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
import org.apache.isis.core.runtime.memento.Memento;
import org.apache.isis.core.runtime.system.context.IsisContext;
import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
@@ -347,6 +353,105 @@ public class ObjectAdapterMemento implements Serializable {
//////////////////////////////////////////////////
+ // Functions
+ //////////////////////////////////////////////////
+
+
+ public final static class Functions {
+
+ private Functions() {
+ }
+
+ public static Function<ObjectSpecification, ObjectSpecId> fromSpec() {
+ return new Function<ObjectSpecification, ObjectSpecId>() {
+
+ @Override
+ public ObjectSpecId apply(final ObjectSpecification from) {
+ return from.getSpecId();
+ }
+ };
+ }
+
+ public static Function<OneToOneAssociation, PropertyMemento> fromProperty() {
+ return new Function<OneToOneAssociation, PropertyMemento>() {
+ @Override
+ public PropertyMemento apply(final OneToOneAssociation from) {
+ return new PropertyMemento(from);
+ }
+ };
+ }
+
+ public static Function<OneToManyAssociation, CollectionMemento> fromCollection() {
+ return new Function<OneToManyAssociation, CollectionMemento>() {
+ @Override
+ public CollectionMemento apply(final OneToManyAssociation from) {
+ return new CollectionMemento(from);
+ }
+ };
+ }
+
+ public static Function<ObjectAction, ActionMemento> fromAction() {
+ return new Function<ObjectAction, ActionMemento>() {
+ @Override
+ public ActionMemento apply(final ObjectAction from) {
+ return new ActionMemento(from);
+ }
+ };
+ }
+
+ public static Function<ObjectActionParameter, ActionParameterMemento> fromActionParameter() {
+ return new Function<ObjectActionParameter, ActionParameterMemento>() {
+ @Override
+ public ActionParameterMemento apply(final ObjectActionParameter from) {
+ return new ActionParameterMemento(from);
+ }
+ };
+ }
+
+ public static Function<Object, ObjectAdapterMemento> fromPojo(final AdapterManager adapterManager) {
+ return new Function<Object, ObjectAdapterMemento>() {
+ @Override
+ public ObjectAdapterMemento apply(final Object pojo) {
+ final ObjectAdapter adapter = adapterManager.adapterFor(pojo);
+ return ObjectAdapterMemento.createOrNull(adapter);
+ }
+ };
+ }
+
+ public static Function<ObjectAdapter, ObjectAdapterMemento> fromAdapter() {
+ return new Function<ObjectAdapter, ObjectAdapterMemento>() {
+ @Override
+ public ObjectAdapterMemento apply(final ObjectAdapter adapter) {
+ return ObjectAdapterMemento.createOrNull(adapter);
+ }
+ };
+ }
+
+
+ public static Function<ObjectAdapterMemento, ObjectAdapter> fromMemento(final ConcurrencyChecking concurrencyChecking) {
+ return new Function<ObjectAdapterMemento, ObjectAdapter>() {
+ @Override
+ public ObjectAdapter apply(final ObjectAdapterMemento from) {
+ return from.getObjectAdapter(concurrencyChecking);
+ }
+ };
+ }
+
+ public static Function<ObjectAdapter, ObjectAdapterMemento> toMemento() {
+ return new Function<ObjectAdapter, ObjectAdapterMemento>() {
+
+ @Override
+ public ObjectAdapterMemento apply(ObjectAdapter from) {
+ return ObjectAdapterMemento.createOrNull(from);
+ }
+
+ };
+ }
+
+ }
+
+
+ //////////////////////////////////////////////////
// Dependencies (from context)
//////////////////////////////////////////////////
http://git-wip-us.apache.org/repos/asf/isis/blob/b717f39f/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java
index 0f21696..74f479d 100644
--- a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java
+++ b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java
@@ -73,12 +73,12 @@ public class EntityCollectionModel extends ModelAbstract<List<ObjectAdapter>> im
STANDALONE {
@Override
List<ObjectAdapter> load(final EntityCollectionModel entityCollectionModel) {
- return Lists.transform(entityCollectionModel.mementoList, ObjectAdapterFunctions.fromMemento());
+ return Lists.transform(entityCollectionModel.mementoList, ObjectAdapterMemento.Functions.fromMemento(ConcurrencyChecking.NO_CHECK));
}
@Override
void setObject(EntityCollectionModel entityCollectionModel, List<ObjectAdapter> list) {
- entityCollectionModel.mementoList = Lists.newArrayList(Lists.transform(list, ObjectAdapterFunctions.toMemento()));
+ entityCollectionModel.mementoList = Lists.newArrayList(Lists.transform(list, ObjectAdapterMemento.Functions.toMemento()));
}
@Override
http://git-wip-us.apache.org/repos/asf/isis/blob/b717f39f/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/MementoFunctions.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/MementoFunctions.java b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/MementoFunctions.java
index 2358e0c..45cfd33 100644
--- a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/MementoFunctions.java
+++ b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/MementoFunctions.java
@@ -36,75 +36,69 @@ import org.apache.isis.viewer.wicket.model.mementos.CollectionMemento;
import org.apache.isis.viewer.wicket.model.mementos.ObjectAdapterMemento;
import org.apache.isis.viewer.wicket.model.mementos.PropertyMemento;
+/**
+ * @deprecated - use {@link ObjectAdapterMemento.Functions}
+ */
+@Deprecated
public final class MementoFunctions {
private MementoFunctions() {
}
+ /**
+ * @deprecated - use {@link ObjectAdapterMemento.Functions}
+ */
+ @Deprecated
public static Function<ObjectSpecification, ObjectSpecId> fromSpec() {
- return new Function<ObjectSpecification, ObjectSpecId>() {
-
- @Override
- public ObjectSpecId apply(final ObjectSpecification from) {
- return from.getSpecId();
- }
- };
+ return ObjectAdapterMemento.Functions.fromSpec();
}
+ /**
+ * @deprecated - use {@link ObjectAdapterMemento.Functions}
+ */
+ @Deprecated
public static Function<OneToOneAssociation, PropertyMemento> fromProperty() {
- return new Function<OneToOneAssociation, PropertyMemento>() {
- @Override
- public PropertyMemento apply(final OneToOneAssociation from) {
- return new PropertyMemento(from);
- }
- };
+ return ObjectAdapterMemento.Functions.fromProperty();
}
+ /**
+ * @deprecated - use {@link ObjectAdapterMemento.Functions}
+ */
+ @Deprecated
public static Function<OneToManyAssociation, CollectionMemento> fromCollection() {
- return new Function<OneToManyAssociation, CollectionMemento>() {
- @Override
- public CollectionMemento apply(final OneToManyAssociation from) {
- return new CollectionMemento(from);
- }
- };
+ return ObjectAdapterMemento.Functions.fromCollection();
}
+ /**
+ * @deprecated - use {@link ObjectAdapterMemento.Functions}
+ */
+ @Deprecated
public static Function<ObjectAction, ActionMemento> fromAction() {
- return new Function<ObjectAction, ActionMemento>() {
- @Override
- public ActionMemento apply(final ObjectAction from) {
- return new ActionMemento(from);
- }
- };
+ return ObjectAdapterMemento.Functions.fromAction();
}
+ /**
+ * @deprecated - use {@link ObjectAdapterMemento.Functions}
+ */
+ @Deprecated
public static Function<ObjectActionParameter, ActionParameterMemento> fromActionParameter() {
- return new Function<ObjectActionParameter, ActionParameterMemento>() {
- @Override
- public ActionParameterMemento apply(final ObjectActionParameter from) {
- return new ActionParameterMemento(from);
- }
- };
+ return ObjectAdapterMemento.Functions.fromActionParameter();
}
+ /**
+ * @deprecated - use {@link ObjectAdapterMemento.Functions}
+ */
+ @Deprecated
public static Function<Object, ObjectAdapterMemento> fromPojo(final AdapterManager adapterManager) {
- return new Function<Object, ObjectAdapterMemento>() {
- @Override
- public ObjectAdapterMemento apply(final Object pojo) {
- final ObjectAdapter adapter = adapterManager.adapterFor(pojo);
- return ObjectAdapterMemento.createOrNull(adapter);
- }
- };
+ return ObjectAdapterMemento.Functions.fromPojo(adapterManager);
}
+ /**
+ * @deprecated - use {@link ObjectAdapterMemento.Functions}
+ */
+ @Deprecated
public static Function<ObjectAdapter, ObjectAdapterMemento> fromAdapter() {
- return new Function<ObjectAdapter, ObjectAdapterMemento>() {
- @Override
- public ObjectAdapterMemento apply(final ObjectAdapter adapter) {
- return ObjectAdapterMemento.createOrNull(adapter);
- }
- };
+ return ObjectAdapterMemento.Functions.fromAdapter();
}
-
}
http://git-wip-us.apache.org/repos/asf/isis/blob/b717f39f/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/ObjectAdapterFunctions.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/ObjectAdapterFunctions.java b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/ObjectAdapterFunctions.java
index 72f1230..7700e04 100644
--- a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/ObjectAdapterFunctions.java
+++ b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/ObjectAdapterFunctions.java
@@ -26,37 +26,37 @@ import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager.ConcurrencyChecking;
import org.apache.isis.viewer.wicket.model.mementos.ObjectAdapterMemento;
+/**
+ * @deprecated - use {@link ObjectAdapter.Functions} or {@link ObjectAdapterMemento.Functions}
+ */
+@Deprecated
public final class ObjectAdapterFunctions {
private ObjectAdapterFunctions() {
}
/**
- * Use {@link ObjectAdapter.Functions}
+ * @deprecated - use {@link ObjectAdapter.Functions}
*/
@Deprecated
public static Function<Object, ObjectAdapter> fromPojo(final AdapterManager adapterManager) {
return ObjectAdapter.Functions.adapterForUsing(adapterManager);
}
- public static Function<ObjectAdapterMemento, ObjectAdapter> fromMemento() {
- return new Function<ObjectAdapterMemento, ObjectAdapter>() {
- @Override
- public ObjectAdapter apply(final ObjectAdapterMemento from) {
- return from.getObjectAdapter(ConcurrencyChecking.NO_CHECK);
- }
- };
+ /**
+ * @deprecated - use {@link ObjectAdapterMemento.Functions}
+ */
+ @Deprecated
+ public static Function<ObjectAdapterMemento, ObjectAdapter> fromMemento(final ConcurrencyChecking concurrencyChecking) {
+ return ObjectAdapterMemento.Functions.fromMemento(concurrencyChecking);
}
+ /**
+ * @deprecated - use {@link ObjectAdapterMemento.Functions}
+ */
+ @Deprecated
public static Function<ObjectAdapter, ObjectAdapterMemento> toMemento() {
- return new Function<ObjectAdapter, ObjectAdapterMemento>() {
-
- @Override
- public ObjectAdapterMemento apply(ObjectAdapter from) {
- return ObjectAdapterMemento.createOrNull(from);
- }
-
- };
+ return ObjectAdapterMemento.Functions.toMemento();
}
}
http://git-wip-us.apache.org/repos/asf/isis/blob/b717f39f/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/OidMatchers.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/OidMatchers.java b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/OidMatchers.java
index ed77526..7904a35 100644
--- a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/OidMatchers.java
+++ b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/OidMatchers.java
@@ -19,45 +19,33 @@
package org.apache.isis.viewer.wicket.model.util;
-import org.hamcrest.Description;
import org.hamcrest.Matcher;
-import org.hamcrest.TypeSafeMatcher;
import org.apache.isis.core.metamodel.adapter.oid.Oid;
+/**
+ * @deprecated - use {@link Oid.Matchers}
+ */
+@Deprecated
public final class OidMatchers {
private OidMatchers() {
}
+ /**
+ * @deprecated - use {@link Oid.Matchers}
+ */
+ @Deprecated
public static Matcher<Oid> isTransient() {
- return new TypeSafeMatcher<Oid>() {
-
- @Override
- public boolean matchesSafely(final Oid item) {
- return item.isTransient();
- }
-
- @Override
- public void describeTo(final Description description) {
- description.appendText("is transient");
- }
- };
+ return Oid.Matchers.isTransient();
}
+ /**
+ * @deprecated - use {@link Oid.Matchers}
+ */
+ @Deprecated
public static Matcher<Oid> isPersistent() {
- return new TypeSafeMatcher<Oid>() {
-
- @Override
- public boolean matchesSafely(final Oid item) {
- return !item.isTransient();
- }
-
- @Override
- public void describeTo(final Description description) {
- description.appendText("is persistent");
- }
- };
+ return Oid.Matchers.isPersistent();
}
}
http://git-wip-us.apache.org/repos/asf/isis/blob/b717f39f/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/BulkActionsLinkFactory.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/BulkActionsLinkFactory.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/BulkActionsLinkFactory.java
index e750c5c..cc3e1d4 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/BulkActionsLinkFactory.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/BulkActionsLinkFactory.java
@@ -28,15 +28,21 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
+import org.apache.wicket.Session;
import org.apache.wicket.extensions.markup.html.repeater.data.table.DataTable;
import org.apache.wicket.markup.html.link.AbstractLink;
import org.apache.wicket.markup.html.link.Link;
import org.apache.isis.applib.annotation.Bulk;
import org.apache.isis.applib.annotation.Bulk.InteractionContext;
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
+import org.apache.isis.core.commons.authentication.MessageBroker;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager.ConcurrencyChecking;
+import org.apache.isis.core.metamodel.adapter.version.ConcurrencyException;
import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.runtime.system.context.IsisContext;
import org.apache.isis.viewer.wicket.model.links.LinkAndLabel;
import org.apache.isis.viewer.wicket.model.mementos.ActionMemento;
import org.apache.isis.viewer.wicket.model.mementos.ObjectAdapterMemento;
@@ -49,6 +55,7 @@ import org.apache.isis.viewer.wicket.ui.components.widgets.cssmenu.CssMenuLinkFa
import org.apache.isis.viewer.wicket.ui.errors.JGrowlBehaviour;
final class BulkActionsLinkFactory implements CssMenuLinkFactory {
+
private static final long serialVersionUID = 1L;
private final EntityCollectionModel model;
@@ -70,38 +77,69 @@ final class BulkActionsLinkFactory implements CssMenuLinkFactory {
@Override
public void onClick() {
final ObjectAction objectAction = actionMemento.getAction();
+ final ConcurrencyChecking concurrencyChecking =
+ ConcurrencyChecking.concurrencyCheckingFor(objectAction.getSemantics());
try {
final List<ObjectAdapterMemento> toggleMementosList = model.getToggleMementosList();
-
- // REVIEW: have disabled concurrency checking here...
- final Iterable<ObjectAdapter> toggledAdapters = Iterables.transform(toggleMementosList, ObjectAdapterFunctions.fromMemento());
+
+ final Iterable<ObjectAdapter> toggledAdapters =
+ Iterables.transform(toggleMementosList, ObjectAdapterMemento.Functions.fromMemento(concurrencyChecking));
final List<Object> domainObjects = Lists.newArrayList(Iterables.transform(toggledAdapters, ObjectAdapter.Functions.getObject()));
- final Bulk.InteractionContext interactionContext = new Bulk.InteractionContext(domainObjects);
- Bulk.InteractionContext.current.set(interactionContext);
- int i=0;
- for(final ObjectAdapter adapter : toggledAdapters) {
-
- int numParameters = objectAction.getParameterCount();
- if(numParameters != 0) {
- return;
+ try {
+ final Bulk.InteractionContext interactionContext = new Bulk.InteractionContext(domainObjects);
+ Bulk.InteractionContext.current.set(interactionContext);
+ int i=0;
+ for(final ObjectAdapter adapter : toggledAdapters) {
+
+ int numParameters = objectAction.getParameterCount();
+ if(numParameters != 0) {
+ return;
+ }
+ interactionContext.setIndex(i++);
+ objectAction.execute(adapter, new ObjectAdapter[]{});
}
- interactionContext.setIndex(i++);
- objectAction.execute(adapter, new ObjectAdapter[]{});
+ } finally {
+ Bulk.InteractionContext.current.set(null);
}
- } finally {
- Bulk.InteractionContext.current.set(null);
- }
-
- model.clearToggleMementosList();
- final ActionModel actionModelHint = model.getActionModelHint();
- if(actionModelHint != null) {
- ObjectAdapter resultAdapter = actionModelHint.getObject();
- model.setObjectList(resultAdapter);
- } else {
+
+ model.clearToggleMementosList();
+ final ActionModel actionModelHint = model.getActionModelHint();
+ if(actionModelHint != null) {
+ ObjectAdapter resultAdapter = actionModelHint.getObject();
+ model.setObjectList(resultAdapter);
+ } else {
+ model.setObject(persistentAdaptersWithin(model.getObject()));
+ }
+
+ } catch(final ConcurrencyException ex) {
+
+ // resync with the objectstore
+ final List<ObjectAdapterMemento> toggleMementosList = Lists.newArrayList(model.getToggleMementosList());
+ for (ObjectAdapterMemento oam : toggleMementosList) {
+ // just requesting the adapter will sync the OAM's version with the objectstore
+ oam.getObjectAdapter(ConcurrencyChecking.NO_CHECK);
+ }
+
+ // discard any adapters that might have been deleted
model.setObject(persistentAdaptersWithin(model.getObject()));
+
+ // attempt to preserve the toggled adapters
+ final List<ObjectAdapter> adapters = model.getObject();
+ model.clearToggleMementosList();
+ for (ObjectAdapterMemento oam : toggleMementosList) {
+ final ObjectAdapter objectAdapter = oam.getObjectAdapter(ConcurrencyChecking.NO_CHECK);
+ if(adapters.contains(objectAdapter)) {
+ // in case it has been deleted...
+ model.toggleSelectionOn(objectAdapter);
+ }
+ }
+
+ // display a warning to the user so that they know that the action wasn't performed
+ getMessageBroker().addWarning(ex.getMessage());
+ return;
}
}
@@ -122,4 +160,19 @@ final class BulkActionsLinkFactory implements CssMenuLinkFactory {
return new LinkAndLabel(link, objectAction.getName(), null, false, explorationOrPrototype, actionIdentifier, cssClass);
}
+
+
+ ///////////////////////////////////////////////////////
+ // Dependencies (from context)
+ ///////////////////////////////////////////////////////
+
+ public AuthenticationSession getAuthenticationSession() {
+ final AuthenticationSessionProvider asa = (AuthenticationSessionProvider) Session.get();
+ return asa.getAuthenticationSession();
+ }
+
+ protected MessageBroker getMessageBroker() {
+ return getAuthenticationSession().getMessageBroker();
+ }
+
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/b717f39f/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTablePanel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTablePanel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTablePanel.java
index 5117132..134344b 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTablePanel.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTablePanel.java
@@ -28,15 +28,21 @@ import com.google.common.collect.Lists;
import com.google.inject.Inject;
import org.apache.wicket.Component;
+import org.apache.wicket.Session;
+import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable;
import org.apache.wicket.extensions.markup.html.repeater.data.table.DataTable;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
import org.apache.wicket.model.Model;
+import org.apache.isis.core.metamodel.adapter.version.ConcurrencyException;
import org.apache.isis.applib.annotation.Where;
import org.apache.isis.applib.filter.Filter;
import org.apache.isis.applib.filter.Filters;
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
+import org.apache.isis.core.commons.authentication.MessageBroker;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager.ConcurrencyChecking;
import org.apache.isis.core.metamodel.facets.hide.HiddenFacet;
@@ -93,7 +99,7 @@ public class CollectionContentsAsAjaxTablePanel extends PanelAbstract<EntityColl
addPropertyColumnsIfRequired(columns);
final SortableDataProvider<ObjectAdapter,String> dataProvider = new CollectionContentsSortableDataProvider(model);
- dataTable = new MyAjaxFallbackDefaultDataTable<ObjectAdapter,String>(ID_TABLE, columns, dataProvider, model.getPageSize());
+ dataTable = new IsisAjaxFallbackDataTable<ObjectAdapter,String>(ID_TABLE, columns, dataProvider, model.getPageSize());
buildEntityActionsGui(bulkActions);
@@ -101,8 +107,8 @@ public class CollectionContentsAsAjaxTablePanel extends PanelAbstract<EntityColl
}
private void addToggleboxColumnIfRequired(final List<IColumn<ObjectAdapter,String>> columns, List<ObjectAction> bulkActions) {
- final EntityCollectionModel model = getModel();
- if(bulkActions.isEmpty() || model.isParented()) {
+ final EntityCollectionModel entityCollectionModel = getModel();
+ if(bulkActions.isEmpty() || entityCollectionModel.isParented()) {
return;
}
@@ -111,8 +117,24 @@ public class CollectionContentsAsAjaxTablePanel extends PanelAbstract<EntityColl
private static final long serialVersionUID = 1L;
@Override
- public void onSelected(final Component context, final ObjectAdapter selectedAdapter) {
- model.toggleSelectionOn(selectedAdapter);
+ public void onSelected(
+ final Component context, final ObjectAdapter selectedAdapter,
+ AjaxRequestTarget ajaxRequestTarget) {
+ entityCollectionModel.toggleSelectionOn(selectedAdapter);
+ }
+
+ @Override
+ public void onConcurrencyException(
+ final Component context, ObjectAdapter selectedAdapter,
+ ConcurrencyException ex,
+ AjaxRequestTarget ajaxRequestTarget) {
+
+ // this causes the row to be repainted
+ // but it isn't possible (yet) to raise any warning
+ // because that only gets flushed on page refresh.
+ //
+ // perhaps something to tackle in a separate ticket....
+ ajaxRequestTarget.add(dataTable);
}
}));
}
@@ -247,4 +269,8 @@ public class CollectionContentsAsAjaxTablePanel extends PanelAbstract<EntityColl
return settings;
}
+ protected MessageBroker getMessageBroker() {
+ return getAuthenticationSession().getMessageBroker();
+ }
+
}
http://git-wip-us.apache.org/repos/asf/isis/blob/b717f39f/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/IsisAjaxFallbackDataTable.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/IsisAjaxFallbackDataTable.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/IsisAjaxFallbackDataTable.java
new file mode 100644
index 0000000..e1b9c14
--- /dev/null
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/IsisAjaxFallbackDataTable.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.isis.viewer.wicket.ui.components.collectioncontents.ajaxtable;
+
+import java.util.List;
+
+import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxNavigationToolbar;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.DataTable;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.ISortableDataProvider;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.NoRecordsToolbar;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.markup.repeater.OddEvenItem;
+import org.apache.wicket.model.IModel;
+
+public class IsisAjaxFallbackDataTable<T, S> extends DataTable<T, S>
+{
+ private static final long serialVersionUID = 1L;
+
+ public IsisAjaxFallbackDataTable(final String id, final List<? extends IColumn<T, S>> columns,
+ final ISortableDataProvider<T, S> dataProvider, final int rowsPerPage)
+ {
+ super(id, columns, dataProvider, rowsPerPage);
+ setOutputMarkupId(true);
+ setVersioned(false);
+ addTopToolbar(new IsisAjaxFallbackHeadersToolbar<S>(this, dataProvider));
+ addBottomToolbar(new AjaxNavigationToolbar(this));
+ addBottomToolbar(new NoRecordsToolbar(this));
+ }
+
+ @Override
+ protected Item<T> newRowItem(final String id, final int index, final IModel<T> model)
+ {
+ return new OddEvenItem<T>(id, index, model);
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/b717f39f/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/IsisAjaxFallbackHeadersToolbar.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/IsisAjaxFallbackHeadersToolbar.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/IsisAjaxFallbackHeadersToolbar.java
new file mode 100644
index 0000000..e59e388
--- /dev/null
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/IsisAjaxFallbackHeadersToolbar.java
@@ -0,0 +1,73 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.isis.viewer.wicket.ui.components.collectioncontents.ajaxtable;
+
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.attributes.IAjaxCallListener;
+import org.apache.wicket.extensions.ajax.markup.html.repeater.data.sort.AjaxFallbackOrderByBorder;
+import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackHeadersToolbar;
+import org.apache.wicket.extensions.markup.html.repeater.data.sort.ISortStateLocator;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.DataTable;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+
+
+/**
+ * Adapted from Wicket's own {@link AjaxFallbackHeadersToolbar}.
+ */
+public class IsisAjaxFallbackHeadersToolbar<S> extends MyHeadersToolbar<S>
+{
+ private static final long serialVersionUID = 1L;
+
+ public IsisAjaxFallbackHeadersToolbar(final DataTable<?, S> table, final ISortStateLocator<S> stateLocator)
+ {
+ super(table, stateLocator);
+ table.setOutputMarkupId(true);
+ }
+
+ @Override
+ protected WebMarkupContainer newSortableHeader(final String borderId, final S property,
+ final ISortStateLocator<S> locator)
+ {
+ return new AjaxFallbackOrderByBorder<S>(borderId, property, locator, getAjaxCallListener())
+ {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ protected void onAjaxClick(final AjaxRequestTarget target)
+ {
+ target.add(getTable());
+ }
+
+ @Override
+ protected void onSortChanged()
+ {
+ super.onSortChanged();
+ getTable().setCurrentPage(0);
+ }
+ };
+ }
+
+ /**
+ * Returns a decorator that will be used to decorate ajax links used in sortable headers
+ *
+ * @return decorator or null for none
+ */
+ protected IAjaxCallListener getAjaxCallListener()
+ {
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/b717f39f/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/MyAjaxFallbackDefaultDataTable.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/MyAjaxFallbackDefaultDataTable.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/MyAjaxFallbackDefaultDataTable.java
deleted file mode 100644
index 91ca852..0000000
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/MyAjaxFallbackDefaultDataTable.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.isis.viewer.wicket.ui.components.collectioncontents.ajaxtable;
-
-import java.util.List;
-
-import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxNavigationToolbar;
-import org.apache.wicket.extensions.markup.html.repeater.data.table.DataTable;
-import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
-import org.apache.wicket.extensions.markup.html.repeater.data.table.ISortableDataProvider;
-import org.apache.wicket.extensions.markup.html.repeater.data.table.NoRecordsToolbar;
-import org.apache.wicket.markup.repeater.Item;
-import org.apache.wicket.markup.repeater.OddEvenItem;
-import org.apache.wicket.model.IModel;
-
-public class MyAjaxFallbackDefaultDataTable<T, S> extends DataTable<T, S>
-{
- private static final long serialVersionUID = 1L;
-
- public MyAjaxFallbackDefaultDataTable(final String id, final List<? extends IColumn<T, S>> columns,
- final ISortableDataProvider<T, S> dataProvider, final int rowsPerPage)
- {
- super(id, columns, dataProvider, rowsPerPage);
- setOutputMarkupId(true);
- setVersioned(false);
- addTopToolbar(new MyAjaxFallbackHeadersToolbar<S>(this, dataProvider));
- addBottomToolbar(new AjaxNavigationToolbar(this));
- addBottomToolbar(new NoRecordsToolbar(this));
- }
-
- @Override
- protected Item<T> newRowItem(final String id, final int index, final IModel<T> model)
- {
- return new OddEvenItem<T>(id, index, model);
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/b717f39f/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/MyAjaxFallbackHeadersToolbar.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/MyAjaxFallbackHeadersToolbar.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/MyAjaxFallbackHeadersToolbar.java
deleted file mode 100644
index e14c496..0000000
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/MyAjaxFallbackHeadersToolbar.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.isis.viewer.wicket.ui.components.collectioncontents.ajaxtable;
-
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.attributes.IAjaxCallListener;
-import org.apache.wicket.extensions.ajax.markup.html.repeater.data.sort.AjaxFallbackOrderByBorder;
-import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackHeadersToolbar;
-import org.apache.wicket.extensions.markup.html.repeater.data.sort.ISortStateLocator;
-import org.apache.wicket.extensions.markup.html.repeater.data.table.DataTable;
-import org.apache.wicket.markup.html.WebMarkupContainer;
-
-
-/**
- * Adapted from Wicket's own {@link AjaxFallbackHeadersToolbar}.
- */
-public class MyAjaxFallbackHeadersToolbar<S> extends MyHeadersToolbar<S>
-{
- private static final long serialVersionUID = 1L;
-
- public MyAjaxFallbackHeadersToolbar(final DataTable<?, S> table, final ISortStateLocator<S> stateLocator)
- {
- super(table, stateLocator);
- table.setOutputMarkupId(true);
- }
-
- @Override
- protected WebMarkupContainer newSortableHeader(final String borderId, final S property,
- final ISortStateLocator<S> locator)
- {
- return new AjaxFallbackOrderByBorder<S>(borderId, property, locator, getAjaxCallListener())
- {
- private static final long serialVersionUID = 1L;
-
- @Override
- protected void onAjaxClick(final AjaxRequestTarget target)
- {
- target.add(getTable());
- }
-
- @Override
- protected void onSortChanged()
- {
- super.onSortChanged();
- getTable().setCurrentPage(0);
- }
- };
- }
-
- /**
- * Returns a decorator that will be used to decorate ajax links used in sortable headers
- *
- * @return decorator or null for none
- */
- protected IAjaxCallListener getAjaxCallListener()
- {
- return null;
- }
-}
http://git-wip-us.apache.org/repos/asf/isis/blob/b717f39f/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/columns/ObjectAdapterToggleboxColumn.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/columns/ObjectAdapterToggleboxColumn.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/columns/ObjectAdapterToggleboxColumn.java
index 8ce2cfc..bf63837 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/columns/ObjectAdapterToggleboxColumn.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/columns/ObjectAdapterToggleboxColumn.java
@@ -24,13 +24,18 @@ import java.util.List;
import com.google.common.collect.Lists;
import org.apache.wicket.Component;
+import org.apache.wicket.Session;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.model.IModel;
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
+import org.apache.isis.core.commons.authentication.MessageBroker;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager.ConcurrencyChecking;
+import org.apache.isis.core.metamodel.adapter.version.ConcurrencyException;
import org.apache.isis.viewer.wicket.model.common.SelectionHandler;
import org.apache.isis.viewer.wicket.model.models.EntityModel;
import org.apache.isis.viewer.wicket.ui.components.widgets.checkbox.ContainedToggleboxPanel;
@@ -70,13 +75,23 @@ public final class ObjectAdapterToggleboxColumn extends ColumnAbstract<ObjectAda
private static final long serialVersionUID = 1L;
@Override
public void onSubmit(AjaxRequestTarget target) {
- final EntityModel o = (EntityModel) rowModel;
- final ObjectAdapter selectedAdapter = o.load(ConcurrencyChecking.NO_CHECK);
- handler.onSelected(this, selectedAdapter);
+ final EntityModel entityModel = (EntityModel) rowModel;
+ ObjectAdapter selectedAdapter = null;
+ try {
+ selectedAdapter = entityModel.load(ConcurrencyChecking.CHECK);
+ handler.onSelected(this, selectedAdapter, target);
+ } catch(ConcurrencyException ex) {
+
+ // should work second time, because the previous attempt will have updated the OAM's OIDs version.
+ selectedAdapter = entityModel.load(ConcurrencyChecking.CHECK);
+ handler.onConcurrencyException(this, selectedAdapter, ex, target);
+ }
}
};
rowToggles.add(toggle);
toggle.setOutputMarkupId(true);
cellItem.add(toggle);
}
+
+
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/b717f39f/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/EntityActionLinkFactory.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/EntityActionLinkFactory.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/EntityActionLinkFactory.java
index 89cb386..6690ced 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/EntityActionLinkFactory.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/EntityActionLinkFactory.java
@@ -99,14 +99,22 @@ public final class EntityActionLinkFactory implements CssMenuLinkFactory {
}
}
+ /**
+ * Creates a link to the {@link ActionPage} (ie the {@link PageClassRegistry registered page} for
+ * {@link PageType#ACTION action}s) with the appropriate {@link PageParameters} to either render the action's
+ * parameter form (if it takes arguments) or to invoke the action directly.
+ *
+ * <p>
+ * If the action's {@link ObjectAction#getSemantics() semantics} are {@link ActionSemantics.Of#SAFE safe}, then
+ * concurrency checking is disabled; otherwise it is enforced.
+ */
private AbstractLink createLinkForPersistent(final String linkId, final ObjectAdapterMemento adapterMemento, final ObjectAction action) {
final ObjectAdapter adapter = adapterMemento.getObjectAdapter(ConcurrencyChecking.NO_CHECK);
final ObjectAdapter contextAdapter = entityModel.getObject();
// use the action semantics to determine whether invoking this action will require a concurrency check or not
// if it's "safe", then we'll just continue without any checking.
- final ConcurrencyChecking concurrencyChecking =
- action.getSemantics() == ActionSemantics.Of.SAFE? ConcurrencyChecking.NO_CHECK: ConcurrencyChecking.CHECK;
+ final ConcurrencyChecking concurrencyChecking = ConcurrencyChecking.concurrencyCheckingFor(action.getSemantics());
final PageParameters pageParameters = ActionModel.createPageParameters(adapter, action, contextAdapter, ActionModel.SingleResultsMode.REDIRECT, concurrencyChecking);
final Class<? extends Page> pageClass = getPageClassRegistry().getPageClass(PageType.ACTION);
return Links.newBookmarkablePageLink(linkId, pageParameters, pageClass);
http://git-wip-us.apache.org/repos/asf/isis/blob/b717f39f/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid.java
index dd4501d..d7687ba 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid.java
@@ -19,6 +19,10 @@
package org.apache.isis.core.metamodel.adapter.oid;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+
import org.apache.isis.applib.annotation.Value;
import org.apache.isis.core.commons.encoding.Encodable;
import org.apache.isis.core.metamodel.adapter.version.Version;
@@ -82,5 +86,43 @@ public interface Oid extends Encodable {
}
}
+
+ public final static class Matchers {
+
+ private Matchers() {
+ }
+
+ public static Matcher<Oid> isTransient() {
+ return new TypeSafeMatcher<Oid>() {
+
+ @Override
+ public boolean matchesSafely(final Oid item) {
+ return item.isTransient();
+ }
+
+ @Override
+ public void describeTo(final Description description) {
+ description.appendText("is transient");
+ }
+ };
+ }
+
+ public static Matcher<Oid> isPersistent() {
+ return new TypeSafeMatcher<Oid>() {
+
+ @Override
+ public boolean matchesSafely(final Oid item) {
+ return !item.isTransient();
+ }
+
+ @Override
+ public void describeTo(final Description description) {
+ description.appendText("is persistent");
+ }
+ };
+ }
+
+ }
+
}