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/03/04 22:58:55 UTC

[6/35] git commit: ISIS-351: concurrency exception shown when hit 'edit' button...

ISIS-351: concurrency exception shown when hit 'edit' button...

... on entity properties form.  Since this is not serious, simply shown as a Notification.

To make supported for ajax buttons, reintroduced the JGrowlBehaviour.


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

Branch: refs/heads/dan/ISIS-233-ro
Commit: 325504c40eaaf9648d4435ac33d4cca5834dd7c2
Parents: a30c737
Author: Dan Haywood <da...@apache.org>
Authored: Fri Mar 1 07:55:03 2013 +0000
Committer: Dan Haywood <da...@apache.org>
Committed: Fri Mar 1 07:55:03 2013 +0000

----------------------------------------------------------------------
 .../integration/wicket/WebRequestCycleForIsis.java |    9 ++-
 .../viewer/wicket/model/models/EntityModel.java    |   17 ++++-
 .../entity/properties/EntityPropertiesForm.java    |   56 +++++++++++++--
 .../wicket/ui/notifications/JGrowlBehaviour.java   |   46 ++++++++++++
 .../viewer/wicket/ui/notifications/JGrowlUtil.java |   38 ++++++++++
 .../isis/viewer/wicket/ui/pages/PageAbstract.java  |   32 +--------
 6 files changed, 156 insertions(+), 42 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/325504c4/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/WebRequestCycleForIsis.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/WebRequestCycleForIsis.java b/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/WebRequestCycleForIsis.java
index 8d547b7..94bb006 100644
--- a/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/WebRequestCycleForIsis.java
+++ b/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/WebRequestCycleForIsis.java
@@ -19,6 +19,7 @@
 
 package org.apache.isis.viewer.wicket.viewer.integration.wicket;
 
+import java.util.Collections;
 import java.util.List;
 
 import org.apache.isis.applib.services.exceprecog.ExceptionRecognizer;
@@ -137,7 +138,13 @@ public class WebRequestCycleForIsis extends AbstractRequestCycleListener {
     }
 
     protected ErrorPage errorPageFor(Exception ex) {
-        List<ExceptionRecognizer> exceptionRecognizers = getServicesInjector().lookupServices(ExceptionRecognizer.class);
+        List<ExceptionRecognizer> exceptionRecognizers;
+        try {
+            exceptionRecognizers = getServicesInjector().lookupServices(ExceptionRecognizer.class);
+        } catch(Exception ex2) {
+            LOG.warn("Unable to obtain exceptionRecognizers (no session?)");
+            exceptionRecognizers = Collections.emptyList();
+        }
         String message = new ExceptionRecognizerComposite(exceptionRecognizers).recognize(ex);
         final ErrorPage page = message != null ? new ErrorPage(message) : new ErrorPage(ex);
         return page;

http://git-wip-us.apache.org/repos/asf/isis/blob/325504c4/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
index 8a3b3c9..8cde3d4 100644
--- a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
+++ b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
@@ -131,6 +131,7 @@ public class EntityModel extends BookmarkableModel<ObjectAdapter> {
      * {@link ConcurrencyException}, if any, that might have occurred previously
      */
     private ConcurrencyException concurrencyException;
+    private ConcurrencyChecking loadingHint;
 
     // //////////////////////////////////////////////////////////
     // constructors
@@ -197,7 +198,7 @@ public class EntityModel extends BookmarkableModel<ObjectAdapter> {
     }
 
     // //////////////////////////////////////////////////////////
-    // load, setObject
+    // loadObject, load, setObject
     // //////////////////////////////////////////////////////////
 
     /**
@@ -211,17 +212,24 @@ public class EntityModel extends BookmarkableModel<ObjectAdapter> {
         }
         
         final ObjectAdapter objectAdapter = adapterMemento.getObjectAdapter(concurrencyChecking);
-        if(concurrencyChecking == ConcurrencyChecking.NO_CHECK) {
-            this.resetPropertyModels();
-        }
         return objectAdapter;
     }
 
+
+    /**
+     * Callback from {@link #getObject()}, defaults to loading the object
+     * using {@link ConcurrencyChecking#CHECK strict} checking.
+     * 
+     * <p>
+     * If non-strict checking is required, then just call {@link #load(ConcurrencyChecking)} with an
+     * argument of {@link ConcurrencyChecking#NO_CHECK} first.
+     */
     @Override
     public ObjectAdapter load() {
         return load(ConcurrencyChecking.CHECK);
     }
 
+
     @Override
     public void setObject(final ObjectAdapter adapter) {
         super.setObject(adapter);
@@ -459,4 +467,5 @@ public class EntityModel extends BookmarkableModel<ObjectAdapter> {
 
 
 
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/325504c4/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityPropertiesForm.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityPropertiesForm.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityPropertiesForm.java
index 168d5cc..347943f 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityPropertiesForm.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityPropertiesForm.java
@@ -46,6 +46,7 @@ import org.apache.isis.viewer.wicket.model.util.ObjectAssociations;
 import org.apache.isis.viewer.wicket.model.util.ObjectSpecifications;
 import org.apache.isis.viewer.wicket.ui.ComponentType;
 import org.apache.isis.viewer.wicket.ui.components.widgets.formcomponent.CancelHintRequired;
+import org.apache.isis.viewer.wicket.ui.notifications.JGrowlBehaviour;
 import org.apache.isis.viewer.wicket.ui.panels.AjaxButtonWithPreSubmitHook;
 import org.apache.isis.viewer.wicket.ui.panels.ButtonWithPreSubmitHook;
 import org.apache.isis.viewer.wicket.ui.panels.FormAbstract;
@@ -53,6 +54,7 @@ import org.apache.isis.viewer.wicket.ui.util.EvenOrOddCssClassAppenderFactory;
 import org.apache.wicket.Component;
 import org.apache.wicket.Session;
 import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
 import org.apache.wicket.feedback.FeedbackMessage;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.basic.Label;
@@ -165,14 +167,20 @@ class EntityPropertiesForm extends FormAbstract<ObjectAdapter> {
     }
 
     private void addButtons() {
-        editButton = new AjaxButtonWithPreSubmitHook(ID_EDIT_BUTTON, Model.of("Edit")) {
+        editButton = new AjaxButton(ID_EDIT_BUTTON, Model.of("Edit")) {
             private static final long serialVersionUID = 1L;
 
             @Override
-            public void preSubmit() {
-                getEntityModel().getObjectAdapterMemento().getObjectAdapter(ConcurrencyChecking.NO_CHECK);
+            public void validate() {
+                try {
+                    getEntityModel().load(ConcurrencyChecking.CHECK);
+                } catch(ConcurrencyException ex) {
+                    getMessageBroker().addMessage("Object changed by " + ex.getOid().getVersion().getUser() + ", automatically reloading");
+                    getEntityModel().load(ConcurrencyChecking.NO_CHECK);
+                }
+                super.validate();
             }
-
+            
             @Override
             public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
                 getEntityModel().resetPropertyModels();
@@ -191,14 +199,21 @@ class EntityPropertiesForm extends FormAbstract<ObjectAdapter> {
 
             @Override
             public void preSubmit() {
+
                 try {
                     getEntityModel().getObjectAdapterMemento().getObjectAdapter(ConcurrencyChecking.CHECK);
                 } catch(ConcurrencyException ex){
+                    // simplify this?
                     Session.get().getFeedbackMessages().add(new FeedbackMessage(EntityPropertiesForm.this, ex.getMessage(), FeedbackMessage.ERROR));
                 }
             }
 
             @Override
+            public void validate() {
+                super.validate();
+            }
+            
+            @Override
             public void onSubmit() {
                 if (getForm().hasError()) {
                     // stay in edit mode
@@ -228,10 +243,15 @@ class EntityPropertiesForm extends FormAbstract<ObjectAdapter> {
                     if(message == null) {
                         throw ex;
                     }
+                    toEditMode(null);
                     return;
                 }
 
-                getEntityModel().resetPropertyModels();
+                try {
+                    getEntityModel().resetPropertyModels();
+                } catch(RuntimeException ex) {
+                    throw ex;
+                }
 
                 toViewMode(null);
             }
@@ -247,8 +267,21 @@ class EntityPropertiesForm extends FormAbstract<ObjectAdapter> {
             }
 
             @Override
+            public void validate() {
+                try {
+                    getEntityModel().load(ConcurrencyChecking.CHECK);
+                } catch(ConcurrencyException ex) {
+                    getMessageBroker().addMessage("Object changed by " + ex.getOid().getVersion().getUser() + ", automatically reloading");
+                    getEntityModel().load(ConcurrencyChecking.NO_CHECK);
+                }
+                super.validate();
+            }
+            
+            @Override
             public void preSubmit() {
-                getEntityModel().getObjectAdapterMemento().getObjectAdapter(ConcurrencyChecking.NO_CHECK);
+                
+                // NO LONGER WORKS...
+                // getEntityModel().getObjectAdapterMemento().getObjectAdapter(ConcurrencyChecking.NO_CHECK);
             }
 
             @Override
@@ -265,7 +298,12 @@ class EntityPropertiesForm extends FormAbstract<ObjectAdapter> {
                         }
                     }
                 });
-                getEntityModel().resetPropertyModels();
+                
+                try {
+                    getEntityModel().resetPropertyModels();
+                } catch(RuntimeException ex) {
+                    throw ex;
+                }
                 toViewMode(target);
             }
 
@@ -278,6 +316,9 @@ class EntityPropertiesForm extends FormAbstract<ObjectAdapter> {
 
         editButton.setOutputMarkupPlaceholderTag(true);
         cancelButton.setOutputMarkupPlaceholderTag(true);
+        
+        editButton.add(new JGrowlBehaviour());
+        cancelButton.add(new JGrowlBehaviour());
     }
 
     private String recognizeException(RuntimeException ex, Component feedbackComponent) {
@@ -326,6 +367,7 @@ class EntityPropertiesForm extends FormAbstract<ObjectAdapter> {
                 String invalidReasonIfAny;
                 try {
                     final ObjectAdapter adapter = entityModel.getObject();
+                    
                     final ValidateObjectFacet facet = adapter.getSpecification().getFacet(ValidateObjectFacet.class);
                     if (facet == null) {
                         return;

http://git-wip-us.apache.org/repos/asf/isis/blob/325504c4/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/notifications/JGrowlBehaviour.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/notifications/JGrowlBehaviour.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/notifications/JGrowlBehaviour.java
new file mode 100644
index 0000000..09a4e23
--- /dev/null
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/notifications/JGrowlBehaviour.java
@@ -0,0 +1,46 @@
+package org.apache.isis.viewer.wicket.ui.notifications;
+
+import org.apache.isis.applib.ApplicationException;
+import org.apache.isis.core.commons.authentication.MessageBroker;
+import org.apache.isis.core.commons.lang.StringUtils;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.wicket.Component;
+import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
+
+
+/**
+ * Attach to any Ajax button that might trigger a notification (ie calls
+ * {@link MessageBroker#addMessage(String)}, {@link MessageBroker#addWarning(String)},
+ * {@link MessageBroker#setApplicationError(String)} or throws an {@link ApplicationException}). 
+ * 
+ * <p>
+ * Attach using the standard Wicket code:
+ * <pre>
+ * Button editButton = new AjaxButton(ID_EDIT_BUTTON, Model.of("Edit")) { ... }
+ * editButton.add(new JGrowlBehaviour());
+ * </pre>
+ */
+public class JGrowlBehaviour extends AbstractDefaultAjaxBehavior {
+
+    private static final long serialVersionUID = 1L;
+
+    @Override
+    protected void respond(AjaxRequestTarget target) {
+        String feedbackMsg = JGrowlUtil.asJGrowlCalls(IsisContext.getMessageBroker());
+        if(!StringUtils.isNullOrEmpty(feedbackMsg)) {
+            target.appendJavaScript(feedbackMsg);
+        }
+    }
+    
+    @Override
+    public void renderHead(Component component, IHeaderResponse response) {
+        super.renderHead(component, response);
+        String feedbackMsg = JGrowlUtil.asJGrowlCalls(IsisContext.getMessageBroker());
+        if(!StringUtils.isNullOrEmpty(feedbackMsg)) {
+            response.render(OnDomReadyHeaderItem.forScript(feedbackMsg));
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/325504c4/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/notifications/JGrowlUtil.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/notifications/JGrowlUtil.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/notifications/JGrowlUtil.java
new file mode 100644
index 0000000..e8cef40
--- /dev/null
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/notifications/JGrowlUtil.java
@@ -0,0 +1,38 @@
+package org.apache.isis.viewer.wicket.ui.notifications;
+
+import org.apache.isis.core.commons.authentication.MessageBroker;
+
+public class JGrowlUtil {
+    
+    private JGrowlUtil(){}
+
+    public static String asJGrowlCalls(MessageBroker messageBroker) {
+        final StringBuilder buf = new StringBuilder();
+        
+        for (String info : messageBroker.getMessages()) {
+            addJGrowlCall(info, "INFO", false, buf);
+        }
+        for (String warning : messageBroker.getWarnings()) {
+            addJGrowlCall(warning, "WARNING", true, buf);
+        }
+        
+        final String error =  messageBroker.getApplicationError();
+        if(error!=null) {
+            addJGrowlCall(error, "ERROR", true, buf);
+        }
+        return buf.toString();
+    }
+
+    private static void addJGrowlCall(final String msg, final String cssClassSuffix, boolean sticky, final StringBuilder buf) {
+        buf.append("$.jGrowl(\"").append(msg).append('\"');
+        buf.append(", {");
+        buf.append("theme: \'jgrowl-").append(cssClassSuffix).append("\'");
+        if (sticky) {
+            buf.append(", sticky: true");
+        }
+        buf.append("}");
+        buf.append(");");
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/325504c4/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/PageAbstract.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/PageAbstract.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/PageAbstract.java
index 8810d2e..d261530 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/PageAbstract.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/PageAbstract.java
@@ -40,6 +40,7 @@ import org.apache.isis.viewer.wicket.ui.ComponentType;
 import org.apache.isis.viewer.wicket.ui.app.registry.ComponentFactoryRegistry;
 import org.apache.isis.viewer.wicket.ui.app.registry.ComponentFactoryRegistryAccessor;
 import org.apache.isis.viewer.wicket.ui.components.actions.ActionPanel;
+import org.apache.isis.viewer.wicket.ui.notifications.JGrowlUtil;
 import org.apache.isis.viewer.wicket.ui.pages.about.AboutPage;
 import org.apache.isis.viewer.wicket.ui.pages.login.WicketSignInPage;
 import org.apache.log4j.Logger;
@@ -135,7 +136,7 @@ public abstract class PageAbstract extends WebPage {
         response.render(JavaScriptHeaderItem.forReference(Application.get().getJavaScriptLibrarySettings().getJQueryReference()));
         response.render(JavaScriptReferenceHeaderItem.forReference(JQUERY_JGROWL_JS));
         
-        final String feedbackMsg = asJGrowlCalls(getMessageBroker());
+        final String feedbackMsg = JGrowlUtil.asJGrowlCalls(getMessageBroker());
         if (!StringUtils.isEmpty(feedbackMsg)) {
             response.render(OnDomReadyHeaderItem.forScript(feedbackMsg));
         }
@@ -148,36 +149,7 @@ public abstract class PageAbstract extends WebPage {
         }
     }
 
-    private String asJGrowlCalls(MessageBroker messageBroker) {
-        final StringBuilder buf = new StringBuilder();
-        
-        for (String info : messageBroker.getMessages()) {
-            addJGrowlCall(info, "INFO", false, buf);
-        }
-        for (String warning : getMessageBroker().getWarnings()) {
-            addJGrowlCall(warning, "WARNING", true, buf);
-        }
-        
-        final String error =  getMessageBroker().getApplicationError();
-        if(error!=null) {
-            addJGrowlCall(error, "ERROR", true, buf);
-        }
-        return buf.toString();
-    }
 
-
-    void addJGrowlCall(final String msg, final String cssClassSuffix, boolean sticky, final StringBuilder buf) {
-        buf.append("$.jGrowl(\"").append(msg).append('\"');
-        buf.append(", {");
-        buf.append("theme: \'jgrowl-").append(cssClassSuffix).append("\'");
-        if (sticky) {
-            buf.append(", sticky: true");
-        }
-        buf.append("}");
-        buf.append(");");
-    }
-
-    
     private void addHomePageLinkAndApplicationName() {
         // this is a bit hacky, but it'll do...
         ExternalLink homePageLink = new ExternalLink(ID_HOME_PAGE_LINK, "/wicket/");