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/02/22 14:27:27 UTC
git commit: ISIS-351: now rendering recognized exceptions on action
panel
Updated Branches:
refs/heads/master b2b72fe09 -> eef7356aa
ISIS-351: now rendering recognized exceptions on action panel
* if the runtime exception is recognized, then will be rendered on the action panel's feedback
rather than the fallback ErrorPage
* also ensured call abortTransaction if an application exception is thrown.
* moved the threadlocal logic for notifications from ActionModel and into ActionPanel.
Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/eef7356a
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/eef7356a
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/eef7356a
Branch: refs/heads/master
Commit: eef7356aa18208c1c3d1fb4b63c7c72e05158ef2
Parents: b2b72fe
Author: Dan Haywood <da...@apache.org>
Authored: Fri Feb 22 13:11:28 2013 +0000
Committer: Dan Haywood <da...@apache.org>
Committed: Fri Feb 22 13:11:28 2013 +0000
----------------------------------------------------------------------
.../ComponentFactoryRegistrarDefault.java | 2 +-
.../viewer/wicket/model/models/ActionExecutor.java | 4 +-
.../viewer/wicket/model/models/ActionModel.java | 22 +--
.../actions/params/ActionParametersFormPanel.css | 19 --
.../actions/params/ActionParametersFormPanel.html | 39 ----
.../actions/params/ActionParametersFormPanel.java | 134 -----------
.../params/ActionParametersFormPanelFactory.java | 52 -----
.../wicket/ui/components/actions/ActionPanel.java | 173 ++++++++++++--
.../actions/ActionParametersFormPanel.css | 19 ++
.../actions/ActionParametersFormPanel.html | 39 ++++
.../actions/ActionParametersFormPanel.java | 136 +++++++++++
.../actions/ActionParametersFormPanelFactory.java | 52 +++++
.../isis/viewer/wicket/ui/pages/PageAbstract.java | 5 +-
13 files changed, 405 insertions(+), 291 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/isis/blob/eef7356a/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java b/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
index 8f55d0b..1de840b 100644
--- a/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
+++ b/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
@@ -24,12 +24,12 @@ import java.util.ServiceLoader;
import com.google.inject.Singleton;
import org.apache.isis.viewer.wicket.ui.ComponentFactory;
-import org.apache.isis.viewer.wicket.ui.actions.params.ActionParametersFormPanelFactory;
import org.apache.isis.viewer.wicket.ui.app.registry.ComponentFactoryRegistrar;
import org.apache.isis.viewer.wicket.ui.components.about.AboutPanelFactory;
import org.apache.isis.viewer.wicket.ui.components.actionlink.ActionLinkPanelFactory;
import org.apache.isis.viewer.wicket.ui.components.actions.ActionInfoPanelFactory;
import org.apache.isis.viewer.wicket.ui.components.actions.ActionPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.actions.ActionParametersFormPanelFactory;
import org.apache.isis.viewer.wicket.ui.components.appactions.cssmenu.AppActionsCssMenuFactory;
import org.apache.isis.viewer.wicket.ui.components.bookmarkedpages.BookmarkedPagesPanelFactory;
import org.apache.isis.viewer.wicket.ui.components.collection.CollectionPanelFactory;
http://git-wip-us.apache.org/repos/asf/isis/blob/eef7356a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionExecutor.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionExecutor.java b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionExecutor.java
index 7869182..ec73fcd 100644
--- a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionExecutor.java
+++ b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionExecutor.java
@@ -21,12 +21,14 @@ package org.apache.isis.viewer.wicket.model.models;
import java.io.Serializable;
+import org.apache.wicket.MarkupContainer;
+
/**
* Decouples the {@link ActionModel}, which needs to delegate the actual
* execution of an action, from its implementor.
*/
public interface ActionExecutor extends Serializable {
- void executeActionAndProcessResults();
+ void executeActionAndProcessResults(MarkupContainer paramForm);
}
http://git-wip-us.apache.org/repos/asf/isis/blob/eef7356a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionModel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionModel.java b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionModel.java
index aed3834..1df27ab 100644
--- a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionModel.java
+++ b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionModel.java
@@ -440,30 +440,16 @@ public class ActionModel extends BookmarkableModel<ObjectAdapter> {
}
- // TODO: hacky!!
- public static ThreadLocal<String> applicationError = new ThreadLocal<String>();
private ObjectAdapter executeAction() {
final ObjectAdapter targetAdapter = getTargetAdapter();
final ObjectAdapter[] arguments = getArgumentsAsArray();
final ObjectAction action = getActionMemento().getAction();
- try {
- final ObjectAdapter results = action.execute(targetAdapter, arguments);
- return results;
- } catch(RuntimeException ex) {
- final ApplicationException appEx = getApplicationExceptionIfAny(ex);
- if(appEx != null) {
- applicationError.set(appEx.getMessage());
- return null;
- }
- throw ex;
- }
- }
- private ApplicationException getApplicationExceptionIfAny(Exception ex) {
- Iterable<ApplicationException> appEx = Iterables.filter(Throwables.getCausalChain(ex), ApplicationException.class);
- Iterator<ApplicationException> iterator = appEx.iterator();
- return iterator.hasNext() ? iterator.next() : null;
+ // let any exceptions propogate, will be caught by UI layer
+ // (ActionPanel at time of writing)
+ final ObjectAdapter results = action.execute(targetAdapter, arguments);
+ return results;
}
public String getReasonInvalidIfAny() {
http://git-wip-us.apache.org/repos/asf/isis/blob/eef7356a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/actions/params/ActionParametersFormPanel.css
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/actions/params/ActionParametersFormPanel.css b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/actions/params/ActionParametersFormPanel.css
deleted file mode 100644
index 9f1612a..0000000
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/actions/params/ActionParametersFormPanel.css
+++ /dev/null
@@ -1,19 +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.
- */
-
http://git-wip-us.apache.org/repos/asf/isis/blob/eef7356a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/actions/params/ActionParametersFormPanel.html
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/actions/params/ActionParametersFormPanel.html b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/actions/params/ActionParametersFormPanel.html
deleted file mode 100644
index 87c6033..0000000
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/actions/params/ActionParametersFormPanel.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-<html>
- <body>
- <wicket:panel>
- <div class="actionParametersForm inputForm">
- <form wicket:id="inputForm"
- method="post">
- <fieldset class="inputFormTable parameters">
- <div wicket:id="parameters" class="parameter">
- <div wicket:id="scalarNameAndValue">[scalar]</div>
- </div>
- <span wicket:id="feedback"></span>
- <div class="buttons">
- <input type="submit" wicket:id="okButton" value="OK" class="okButton"/>
- </div>
- </fieldset>
- </form>
- </div>
- </wicket:panel>
- </body>
-</html>
http://git-wip-us.apache.org/repos/asf/isis/blob/eef7356a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/actions/params/ActionParametersFormPanel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/actions/params/ActionParametersFormPanel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/actions/params/ActionParametersFormPanel.java
deleted file mode 100644
index b875f5a..0000000
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/actions/params/ActionParametersFormPanel.java
+++ /dev/null
@@ -1,134 +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.actions.params;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.CoreMatchers.nullValue;
-
-import java.util.List;
-
-import com.google.common.collect.Lists;
-
-import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.markup.html.form.Button;
-import org.apache.wicket.markup.html.form.Form;
-import org.apache.wicket.markup.repeater.RepeatingView;
-
-import org.apache.isis.core.commons.ensure.Ensure;
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
-import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
-import org.apache.isis.viewer.wicket.model.mementos.ActionParameterMemento;
-import org.apache.isis.viewer.wicket.model.models.ActionExecutor;
-import org.apache.isis.viewer.wicket.model.models.ActionModel;
-import org.apache.isis.viewer.wicket.model.models.ScalarModel;
-import org.apache.isis.viewer.wicket.model.util.Mementos;
-import org.apache.isis.viewer.wicket.ui.ComponentType;
-import org.apache.isis.viewer.wicket.ui.components.widgets.formcomponent.FormFeedbackPanel;
-import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
-
-/**
- * {@link PanelAbstract Panel} to capture the arguments for an action
- * invocation.
- */
-public class ActionParametersFormPanel extends PanelAbstract<ActionModel> {
-
- private static final long serialVersionUID = 1L;
-
- private static final String ID_OK_BUTTON = "okButton";
- private static final String ID_ACTION_PARAMETERS = "parameters";
-
- private final ActionExecutor actionExecutor;
-
- public ActionParametersFormPanel(final String id, final ActionModel model) {
- super(id, model);
-
- Ensure.ensureThatArg(model.getExecutor(), is(not(nullValue())));
-
- this.actionExecutor = model.getExecutor();
- buildGui();
- }
-
- private void buildGui() {
- add(new ActionParameterForm("inputForm", getModel()));
- }
-
- class ActionParameterForm extends Form<ObjectAdapter> {
-
- private static final long serialVersionUID = 1L;
-
- private static final String ID_FEEDBACK = "feedback";
-
- public ActionParameterForm(final String id, final ActionModel actionModel) {
- super(id, actionModel);
-
- addParameters();
-
- addOrReplace(new FormFeedbackPanel(ID_FEEDBACK));
- addOkButton();
- }
-
- private ActionModel getActionModel() {
- return (ActionModel) super.getModel();
- }
-
- private void addParameters() {
- final ActionModel actionModel = getActionModel();
- final ObjectAction objectAction = actionModel.getActionMemento().getAction();
-
- final List<ObjectActionParameter> parameters = objectAction.getParameters();
-
- final List<ActionParameterMemento> mementos = buildParameterMementos(parameters);
- for (final ActionParameterMemento apm1 : mementos) {
- actionModel.getArgumentModel(apm1);
- }
-
- final RepeatingView rv = new RepeatingView(ID_ACTION_PARAMETERS);
- add(rv);
- for (final ActionParameterMemento apm : mementos) {
- final WebMarkupContainer container = new WebMarkupContainer(rv.newChildId());
- rv.add(container);
-
- final ScalarModel argumentModel = actionModel.getArgumentModel(apm);
- getComponentFactoryRegistry().addOrReplaceComponent(container, ComponentType.SCALAR_NAME_AND_VALUE, argumentModel);
- }
- }
-
- private void addOkButton() {
- add(new Button(ID_OK_BUTTON) {
- private static final long serialVersionUID = 1L;
-
- @Override
- public void onSubmit() {
- actionExecutor.executeActionAndProcessResults();
- };
- });
- }
-
- private List<ActionParameterMemento> buildParameterMementos(final List<ObjectActionParameter> parameters) {
- final List<ActionParameterMemento> parameterMementoList = Lists.transform(parameters, Mementos.fromActionParameter());
- // we copy into a new array list otherwise we get lazy evaluation =
- // reference to a non-serializable object
- return Lists.newArrayList(parameterMementoList);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/isis/blob/eef7356a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/actions/params/ActionParametersFormPanelFactory.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/actions/params/ActionParametersFormPanelFactory.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/actions/params/ActionParametersFormPanelFactory.java
deleted file mode 100644
index 0d67112..0000000
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/actions/params/ActionParametersFormPanelFactory.java
+++ /dev/null
@@ -1,52 +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.actions.params;
-
-import org.apache.wicket.Component;
-import org.apache.wicket.model.IModel;
-
-import org.apache.isis.viewer.wicket.model.models.ActionModel;
-import org.apache.isis.viewer.wicket.ui.ComponentFactory;
-import org.apache.isis.viewer.wicket.ui.ComponentFactoryAbstract;
-import org.apache.isis.viewer.wicket.ui.ComponentType;
-
-/**
- * {@link ComponentFactory} for {@link ActionParametersFormPanel}.
- */
-public class ActionParametersFormPanelFactory extends ComponentFactoryAbstract {
-
- private static final long serialVersionUID = 1L;
-
- public ActionParametersFormPanelFactory() {
- super(ComponentType.PARAMETERS);
- }
-
- @Override
- public ApplicationAdvice appliesTo(final IModel<?> model) {
- return appliesIf(model instanceof ActionModel);
- }
-
- @Override
- public Component createComponent(final String id, final IModel<?> model) {
- final ActionModel actionModel = (ActionModel) model;
- return new ActionParametersFormPanel(id, actionModel);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/isis/blob/eef7356a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionPanel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionPanel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionPanel.java
index fd9cacb..367a469 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionPanel.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionPanel.java
@@ -20,18 +20,26 @@
package org.apache.isis.viewer.wicket.ui.components.actions;
import java.util.Arrays;
+import java.util.Iterator;
import java.util.List;
+import org.apache.wicket.MarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.model.Model;
+import org.apache.isis.applib.ApplicationException;
import org.apache.isis.applib.annotation.ActionSemantics;
+import org.apache.isis.applib.services.exceprecog.ExceptionRecognizer;
+import org.apache.isis.applib.services.exceprecog.ExceptionRecognizerComposite;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.adapter.version.ConcurrencyException;
import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjector;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.core.runtime.system.transaction.IsisTransaction;
+import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
import org.apache.isis.viewer.wicket.model.common.SelectionHandler;
import org.apache.isis.viewer.wicket.model.isis.PersistenceSessionProvider;
import org.apache.isis.viewer.wicket.model.models.ActionExecutor;
@@ -44,9 +52,13 @@ import org.apache.isis.viewer.wicket.model.models.ValueModel;
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.pages.BookmarkedPagesModelProvider;
+import org.apache.isis.viewer.wicket.ui.pages.PageAbstract;
import org.apache.isis.viewer.wicket.ui.pages.entity.EntityPage;
import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
+import com.google.common.base.Throwables;
+import com.google.common.collect.Iterables;
+
/**
* {@link PanelAbstract Panel} representing an action invocation, backed by an
* {@link ActionModel}.
@@ -82,7 +94,7 @@ public class ActionPanel extends PanelAbstract<ActionModel> implements ActionExe
if (actionModel.getActionMode() == ActionModel.Mode.PARAMETERS) {
buildGuiForParameters(actionModel);
} else {
- executeActionAndProcessResults();
+ executeActionAndProcessResults(null);
}
}
@@ -108,38 +120,29 @@ public class ActionPanel extends PanelAbstract<ActionModel> implements ActionExe
return application.getBookmarkedPagesModel();
}
+
+ /**
+ * @param feedbackForm - for feedback messages.
+ */
@Override
- public void executeActionAndProcessResults() {
+ public void executeActionAndProcessResults(MarkupContainer feedbackForm) {
permanentlyHide(ComponentType.ENTITY_ICON_AND_TITLE);
-
ObjectAdapter targetAdapter = null;
+ boolean clearArgs = true;
try {
+
targetAdapter = getModel().getTargetAdapter();
- // validate the action parameters (if any)
- final ActionModel actionModel = getActionModel();
- final String invalidReasonIfAny = actionModel.getReasonInvalidIfAny();
- if (invalidReasonIfAny != null) {
- error(invalidReasonIfAny);
- return;
- }
+ // no concurrency exception, so continue...
+ clearArgs = executeActionOnTargetAndProcessResults(targetAdapter, feedbackForm);
- // executes the action
- ObjectAdapter resultAdapter = actionModel.getObject();
-
- final ResultType resultType = ResultType.determineFor(resultAdapter);
- resultType.addResults(this, resultAdapter);
-
- if(actionModel.hasSafeActionSemantics()) {
- bookmarkPage(actionModel);
- }
+ } catch (ConcurrencyException ex) {
- } catch(ConcurrencyException ex) {
-
- // second attempt should succeed, because the Oid would have been updated in the attempt
- if(targetAdapter == null) {
+ // second attempt should succeed, because the Oid would have
+ // been updated in the attempt
+ if (targetAdapter == null) {
targetAdapter = getModel().getTargetAdapter();
}
@@ -148,12 +151,116 @@ public class ActionPanel extends PanelAbstract<ActionModel> implements ActionExe
resultType.addResults(this, targetAdapter, ex);
return;
+
} finally {
- final ActionModel actionModel = getActionModel();
- actionModel.clearArguments();
+ if(clearArgs) {
+ getActionModel().clearArguments();
+ }
}
}
+ /**
+ * @return - whether action arguments should be cleared or not.
+ */
+ private boolean executeActionOnTargetAndProcessResults(ObjectAdapter targetAdapter, MarkupContainer feedbackOwner) {
+
+ // validate the action parameters (if any)
+ final ActionModel actionModel = getActionModel();
+ final String invalidReasonIfAny = actionModel.getReasonInvalidIfAny();
+ if (invalidReasonIfAny != null) {
+ feedbackOwner.error(invalidReasonIfAny);
+ return false;
+ }
+
+ // the object store could raise an exception (eg uniqueness constraint)
+ // so we handle it here.
+ try {
+ // could be programmatic flushing, so must include in the try... finally
+ final ObjectAdapter resultAdapter = executeActionHandlingApplicationExceptions(feedbackOwner);
+
+ final ResultType resultType = ResultType.determineFor(resultAdapter);
+
+ // this will flush any queued changes, so exception (if any)
+ // will be thrown here
+ resultType.addResults(this, resultAdapter);
+
+ } catch (RuntimeException ex) {
+
+ // see if the exception is recognized as being a non-serious error
+ // (nb: similar code in WebRequestCycleForIsis, as a fallback)
+ List<ExceptionRecognizer> exceptionRecognizers = getServicesInjector().lookupServices(ExceptionRecognizer.class);
+ String message = new ExceptionRecognizerComposite(exceptionRecognizers).recognize(ex);
+ if(message != null) {
+ // recognized
+ feedbackOwner.error(message);
+ getTransactionManager().abortTransaction();
+ return false;
+ }
+
+ // not handled, so propagate
+ throw ex;
+ }
+
+ if (actionModel.hasSafeActionSemantics()) {
+ bookmarkPage(actionModel);
+ }
+
+ return true;
+ }
+
+ /**
+ * The executeAction method will set a value on the thread if an
+ * {@link ApplicationException} is thrown. This will allow the exception
+ * to be rendered in the usual way (using jGrowl). Once rendered,
+ * this {@link ThreadLocal} will be cleared (see {@link PageAbstract}).
+ *
+ * <p>
+ * Using a {@link ThreadLocal} is always a bit hacky, but will do, I think.
+ */
+ public static ThreadLocal<String> applicationError = new ThreadLocal<String>();
+
+
+ /**
+ * Executes the action, handling any {@link ApplicationException}s that
+ * might be encountered.
+ *
+ * <p>
+ * If an {@link ApplicationException} is encountered, then the {@link #applicationError} thread-local
+ * will be set so that a suitable message can be rendered, and the current {@link IsisTransaction transaction}
+ * will also be aborted.
+ *
+ * <p>
+ * Any other types of exception will be ignored (to be picked up higher up in the callstack).
+ * @param feedbackOwner
+ */
+ private ObjectAdapter executeActionHandlingApplicationExceptions(MarkupContainer feedbackOwner) {
+ final ActionModel actionModel = getActionModel();
+ try {
+ ObjectAdapter resultAdapter = actionModel.getObject();
+ return resultAdapter;
+
+ } catch (RuntimeException ex) {
+
+ // see if is an application-defined exception
+ final ApplicationException appEx = getApplicationExceptionIfAny(ex);
+ if (appEx != null) {
+ applicationError.set(appEx.getMessage());
+ getTransactionManager().abortTransaction();
+ return null;
+ }
+
+ // not handled, so propagate
+ throw ex;
+ }
+ }
+
+ private ApplicationException getApplicationExceptionIfAny(Exception ex) {
+ Iterable<ApplicationException> appEx = Iterables.filter(Throwables.getCausalChain(ex), ApplicationException.class);
+ Iterator<ApplicationException> iterator = appEx.iterator();
+ return iterator.hasNext() ? iterator.next() : null;
+ }
+
+
enum ResultType {
OBJECT {
@Override
@@ -317,4 +424,20 @@ public class ActionPanel extends PanelAbstract<ActionModel> implements ActionExe
hideAllBut();
}
+
+ ///////////////////////////////////////////////////////
+ // Dependencies (from context)
+ ///////////////////////////////////////////////////////
+
+ protected IsisTransactionManager getTransactionManager() {
+ return IsisContext.getTransactionManager();
+ }
+
+ /**
+ * Factored out so can be overridden in testing.
+ */
+ protected ServicesInjector getServicesInjector() {
+ return IsisContext.getPersistenceSession().getServicesInjector();
+ }
+
}
http://git-wip-us.apache.org/repos/asf/isis/blob/eef7356a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanel.css
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanel.css b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanel.css
new file mode 100644
index 0000000..9f1612a
--- /dev/null
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanel.css
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
http://git-wip-us.apache.org/repos/asf/isis/blob/eef7356a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanel.html
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanel.html b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanel.html
new file mode 100644
index 0000000..87c6033
--- /dev/null
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanel.html
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<html>
+ <body>
+ <wicket:panel>
+ <div class="actionParametersForm inputForm">
+ <form wicket:id="inputForm"
+ method="post">
+ <fieldset class="inputFormTable parameters">
+ <div wicket:id="parameters" class="parameter">
+ <div wicket:id="scalarNameAndValue">[scalar]</div>
+ </div>
+ <span wicket:id="feedback"></span>
+ <div class="buttons">
+ <input type="submit" wicket:id="okButton" value="OK" class="okButton"/>
+ </div>
+ </fieldset>
+ </form>
+ </div>
+ </wicket:panel>
+ </body>
+</html>
http://git-wip-us.apache.org/repos/asf/isis/blob/eef7356a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanel.java
new file mode 100644
index 0000000..90651ea
--- /dev/null
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanel.java
@@ -0,0 +1,136 @@
+/*
+ * 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.actions;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.nullValue;
+
+import java.util.List;
+
+import com.google.common.collect.Lists;
+
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.Button;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.repeater.RepeatingView;
+
+import org.apache.isis.core.commons.ensure.Ensure;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
+import org.apache.isis.viewer.wicket.model.mementos.ActionParameterMemento;
+import org.apache.isis.viewer.wicket.model.models.ActionExecutor;
+import org.apache.isis.viewer.wicket.model.models.ActionModel;
+import org.apache.isis.viewer.wicket.model.models.ScalarModel;
+import org.apache.isis.viewer.wicket.model.util.Mementos;
+import org.apache.isis.viewer.wicket.ui.ComponentType;
+import org.apache.isis.viewer.wicket.ui.components.widgets.formcomponent.FormFeedbackPanel;
+import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
+
+/**
+ * {@link PanelAbstract Panel} to capture the arguments for an action
+ * invocation.
+ */
+public class ActionParametersFormPanel extends PanelAbstract<ActionModel> {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final String ID_OK_BUTTON = "okButton";
+ private static final String ID_ACTION_PARAMETERS = "parameters";
+
+ private final ActionExecutor actionExecutor;
+
+ public ActionParametersFormPanel(final String id, final ActionModel model) {
+ super(id, model);
+
+ Ensure.ensureThatArg(model.getExecutor(), is(not(nullValue())));
+
+ this.actionExecutor = model.getExecutor();
+ buildGui();
+ }
+
+ private void buildGui() {
+ add(new ActionParameterForm("inputForm", getModel()));
+ }
+
+ class ActionParameterForm extends Form<ObjectAdapter> {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final String ID_FEEDBACK = "feedback";
+
+ public ActionParameterForm(final String id, final ActionModel actionModel) {
+ super(id, actionModel);
+
+ addParameters();
+
+ FormFeedbackPanel formFeedback = new FormFeedbackPanel(ID_FEEDBACK);
+ formFeedback.setEscapeModelStrings(false);
+ addOrReplace(formFeedback);
+ addOkButton();
+ }
+
+ private ActionModel getActionModel() {
+ return (ActionModel) super.getModel();
+ }
+
+ private void addParameters() {
+ final ActionModel actionModel = getActionModel();
+ final ObjectAction objectAction = actionModel.getActionMemento().getAction();
+
+ final List<ObjectActionParameter> parameters = objectAction.getParameters();
+
+ final List<ActionParameterMemento> mementos = buildParameterMementos(parameters);
+ for (final ActionParameterMemento apm1 : mementos) {
+ actionModel.getArgumentModel(apm1);
+ }
+
+ final RepeatingView rv = new RepeatingView(ID_ACTION_PARAMETERS);
+ add(rv);
+ for (final ActionParameterMemento apm : mementos) {
+ final WebMarkupContainer container = new WebMarkupContainer(rv.newChildId());
+ rv.add(container);
+
+ final ScalarModel argumentModel = actionModel.getArgumentModel(apm);
+ getComponentFactoryRegistry().addOrReplaceComponent(container, ComponentType.SCALAR_NAME_AND_VALUE, argumentModel);
+ }
+ }
+
+ private void addOkButton() {
+ add(new Button(ID_OK_BUTTON) {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void onSubmit() {
+ actionExecutor.executeActionAndProcessResults(ActionParameterForm.this);
+ };
+ });
+ }
+
+ private List<ActionParameterMemento> buildParameterMementos(final List<ObjectActionParameter> parameters) {
+ final List<ActionParameterMemento> parameterMementoList = Lists.transform(parameters, Mementos.fromActionParameter());
+ // we copy into a new array list otherwise we get lazy evaluation =
+ // reference to a non-serializable object
+ return Lists.newArrayList(parameterMementoList);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/eef7356a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanelFactory.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanelFactory.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanelFactory.java
new file mode 100644
index 0000000..95229f0
--- /dev/null
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanelFactory.java
@@ -0,0 +1,52 @@
+/*
+ * 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.actions;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.model.IModel;
+
+import org.apache.isis.viewer.wicket.model.models.ActionModel;
+import org.apache.isis.viewer.wicket.ui.ComponentFactory;
+import org.apache.isis.viewer.wicket.ui.ComponentFactoryAbstract;
+import org.apache.isis.viewer.wicket.ui.ComponentType;
+
+/**
+ * {@link ComponentFactory} for {@link ActionParametersFormPanel}.
+ */
+public class ActionParametersFormPanelFactory extends ComponentFactoryAbstract {
+
+ private static final long serialVersionUID = 1L;
+
+ public ActionParametersFormPanelFactory() {
+ super(ComponentType.PARAMETERS);
+ }
+
+ @Override
+ public ApplicationAdvice appliesTo(final IModel<?> model) {
+ return appliesIf(model instanceof ActionModel);
+ }
+
+ @Override
+ public Component createComponent(final String id, final IModel<?> model) {
+ final ActionModel actionModel = (ActionModel) model;
+ return new ActionParametersFormPanel(id, actionModel);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/eef7356a/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 66e10b6..7b36cff 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
@@ -38,6 +38,7 @@ import org.apache.isis.viewer.wicket.ui.ComponentFactory;
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.pages.about.AboutPage;
import org.apache.isis.viewer.wicket.ui.pages.login.WicketSignInPage;
import org.apache.log4j.Logger;
@@ -158,12 +159,12 @@ public abstract class PageAbstract extends WebPage {
}
try {
- final String error = ActionModel.applicationError.get();
+ final String error = ActionPanel.applicationError.get();
if(error!=null) {
addJGrowlCall(error, "ERROR", true, buf);
}
} finally {
- ActionModel.applicationError.remove();
+ ActionPanel.applicationError.remove();
}
return buf.toString();
}