You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by rm...@apache.org on 2013/03/24 18:45:14 UTC
[17/24] Restructuring Scimpi to remove dependencies and enable easier
testing.
http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/LinkedFieldsBlock.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/LinkedFieldsBlock.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/LinkedFieldsBlock.java
deleted file mode 100644
index 5049a3d..0000000
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/LinkedFieldsBlock.java
+++ /dev/null
@@ -1,47 +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.scimpi.dispatcher.view.field;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
-
-public class LinkedFieldsBlock extends InclusionList {
- private final Map<String, LinkedObject> linkedFields = new HashMap<String, LinkedObject>();
-
- public void link(final String field, final String variable, final String scope, final String forwardView) {
- include(field);
- linkedFields.put(field, new LinkedObject(variable, scope, forwardView));
- }
-
- public LinkedObject[] linkedFields(final List<ObjectAssociation> fields) {
- final LinkedObject[] includedFields = new LinkedObject[fields.size()];
- for (int i = 0; i < fields.size(); i++) {
- final String id2 = fields.get(i).getId();
- if (fields.get(i).isOneToOneAssociation() && linkedFields.containsKey(id2)) {
- includedFields[i] = linkedFields.get(id2);
- }
- }
- return includedFields;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/LinkedObject.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/LinkedObject.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/LinkedObject.java
deleted file mode 100644
index 934e1c1..0000000
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/LinkedObject.java
+++ /dev/null
@@ -1,58 +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.scimpi.dispatcher.view.field;
-
-import org.apache.isis.viewer.scimpi.Names;
-import org.apache.isis.viewer.scimpi.dispatcher.context.Request.Scope;
-
-public class LinkedObject {
- private final String variable;
- private final String scope;
- private String forwardView;
-
- public LinkedObject(final String variable, final String scope, final String forwardView) {
- this.variable = variable;
- this.scope = scope;
- this.forwardView = forwardView;
- }
-
- public LinkedObject(final String forwardView) {
- this.forwardView = forwardView;
- scope = Scope.INTERACTION.toString();
- variable = Names.RESULT;
- }
-
- public String getVariable() {
- return variable;
- }
-
- public String getScope() {
- return scope;
- }
-
- public String getForwardView() {
- return forwardView;
- }
-
- public void setForwardView(final String path) {
- forwardView = path;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/ActionFormAbstract.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/ActionFormAbstract.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/ActionFormAbstract.java
new file mode 100644
index 0000000..f3fa4dd
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/ActionFormAbstract.java
@@ -0,0 +1,223 @@
+package org.apache.isis.viewer.scimpi.dispatcher.view.form;
+
+import java.util.List;
+
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+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.viewer.scimpi.Names;
+import org.apache.isis.viewer.scimpi.ScimpiException;
+import org.apache.isis.viewer.scimpi.dispatcher.action.ActionAction;
+import org.apache.isis.viewer.scimpi.dispatcher.context.Request;
+import org.apache.isis.viewer.scimpi.dispatcher.context.Request.Scope;
+import org.apache.isis.viewer.scimpi.dispatcher.form.FieldEditState;
+import org.apache.isis.viewer.scimpi.dispatcher.form.FormState;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.util.MethodsUtils;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
+
+// TODO combine the common stuff that is found here and in EditFormAbstract and LoginFormAbstract
+public abstract class ActionFormAbstract extends AbstractElementProcessor {
+
+ private static final Where where = Where.OBJECT_FORMS;
+
+ public static void createForm(final TemplateProcessor templateProcessor, final CreateFormParameter parameterObject) {
+ createForm(templateProcessor, parameterObject, false);
+ }
+
+ public static void createForm(final TemplateProcessor templateProcessor, final CreateFormParameter parameterObject, final boolean withoutProcessing) {
+ final Request context = templateProcessor.getContext();
+ final ObjectAdapter object = MethodsUtils.findObject(context, parameterObject.objectId);
+ final String version = templateProcessor.getContext().mapVersion(object);
+ final ObjectAction action = MethodsUtils.findAction(object, parameterObject.methodName);
+ // TODO how do we distinguish between overloaded methods?
+
+ // REVIEW Is this useful?
+ if (action.getParameterCount() == 0) {
+ throw new ScimpiException("Action form can only be used for actions with parameters");
+ }
+ if (parameterObject.showMessage && MethodsUtils.isVisible(object, action, where)) {
+ final String notUsable = MethodsUtils.isUsable(object, action, where);
+ if (notUsable != null) {
+ if (!withoutProcessing) {
+ templateProcessor.skipUntilClose();
+ }
+ templateProcessor.appendHtml("<div class=\"" + parameterObject.className + "-message\" >");
+ templateProcessor.appendAsHtmlEncoded(notUsable);
+ templateProcessor.appendHtml("</div>");
+ return;
+ }
+ }
+ if (!MethodsUtils.isVisibleAndUsable(object, action, where)) {
+ if (!withoutProcessing) {
+ templateProcessor.skipUntilClose();
+ }
+ return;
+ }
+ final String objectId = context.mapObject(object, Scope.INTERACTION);
+ final String errorView = context.fullFilePath(parameterObject.forwardErrorTo == null ? context.getResourceFile() : parameterObject.forwardErrorTo);
+ final String voidView = context.fullFilePath(parameterObject.forwardVoidTo == null ? context.getResourceFile() : parameterObject.forwardVoidTo);
+ if (action.isContributed() && !action.hasReturn() && parameterObject.resultOverride == null) {
+ parameterObject.resultOverride = objectId;
+ }
+ final HiddenInputField[] hiddenFields = new HiddenInputField[] { new HiddenInputField("_" + OBJECT, objectId), new HiddenInputField("_" + VERSION, version), new HiddenInputField("_" + FORM_ID, parameterObject.formId), new HiddenInputField("_" + METHOD, parameterObject.methodName),
+ parameterObject.forwardResultTo == null ? null : new HiddenInputField("_" + VIEW, context.fullFilePath(parameterObject.forwardResultTo)), new HiddenInputField("_" + VOID, voidView), new HiddenInputField("_" + ERROR, errorView),
+ parameterObject.completionMessage == null ? null : new HiddenInputField("_" + MESSAGE, parameterObject.completionMessage), parameterObject.scope == null ? null : new HiddenInputField("_" + SCOPE, parameterObject.scope),
+ parameterObject.resultOverride == null ? null : new HiddenInputField("_" + RESULT_OVERRIDE, parameterObject.resultOverride), parameterObject.resultName == null ? null : new HiddenInputField("_" + RESULT_NAME, parameterObject.resultName),
+ parameterObject.resultName == null ? null : new HiddenInputField(Names.RESULT, (String) templateProcessor.getContext().getVariable(Names.RESULT)) };
+
+ // TODO when the block contains a selector tag it doesn't disable it if
+ // the field cannot be edited!!!
+ final FormFieldBlock containedBlock = new FormFieldBlock() {
+ @Override
+ public boolean isNullable(final String name) {
+ final int index = Integer.parseInt(name.substring(5)) - 1;
+ final ObjectActionParameter param = action.getParameters().get(index);
+ return param.isOptional();
+ }
+ };
+ templateProcessor.pushBlock(containedBlock);
+ if (!withoutProcessing) {
+ templateProcessor.processUtilCloseTag();
+ }
+
+ final FormState entryState = (FormState) context.getVariable(ENTRY_FIELDS);
+
+ // TODO the list of included fields should be considered in the next
+ // method (see EditObject)
+ final InputField[] formFields = createFields(action, object);
+ hideExcludedParameters(containedBlock, formFields);
+ containedBlock.setUpValues(formFields);
+ initializeFields(context, object, action, formFields);
+ setDefaults(context, object, action, formFields, entryState, parameterObject.showIcon);
+ String errors = null;
+ if (entryState != null && entryState.isForForm(parameterObject.formId)) {
+ copyEntryState(context, object, action, formFields, entryState);
+ errors = entryState.getError();
+ }
+ overrideWithHtml(context, containedBlock, formFields);
+
+ String formTitle;
+ if (parameterObject.formTitle == null) {
+ formTitle = action.getName();
+ } else {
+ formTitle = parameterObject.formTitle;
+ }
+
+ String buttonTitle = parameterObject.buttonTitle;
+ if (buttonTitle == null) {
+ buttonTitle = action.getName();
+ } else if (buttonTitle.equals("")) {
+ buttonTitle = "Ok";
+ }
+
+ HtmlFormBuilder.createForm(templateProcessor, ActionAction.ACTION + ".app", hiddenFields, formFields, parameterObject.className,
+ parameterObject.id, formTitle, parameterObject.labelDelimiter, action.getDescription(), action.getHelp(), buttonTitle, errors, parameterObject.cancelTo);
+
+ templateProcessor.popBlock();
+ }
+
+ private static void hideExcludedParameters(final FormFieldBlock containedBlock, final InputField[] formFields) {
+ for (final InputField inputField : formFields) {
+ final String id2 = inputField.getName();
+ if (!containedBlock.includes(id2)) {
+ inputField.setHidden(true);
+ }
+ }
+ }
+
+ private static InputField[] createFields(final ObjectAction action, final ObjectAdapter object) {
+ final int parameterCount = action.getParameterCount();
+ final InputField[] fields = new InputField[parameterCount];
+ for (int i = 0; i < fields.length; i++) {
+ fields[i] = new InputField(ActionAction.parameterName(i));
+ }
+ return fields;
+ }
+
+ private static void initializeFields(final Request context, final ObjectAdapter object, final ObjectAction action, final InputField[] fields) {
+ final List<ObjectActionParameter> parameters = action.getParameters();
+ for (int i = 0; i < fields.length; i++) {
+ final InputField field = fields[i];
+ final ObjectActionParameter param = parameters.get(i);
+ if (action.isContributed() && i == 0) {
+ // fields[i].setValue(context.mapObject(object,
+ // Scope.INTERACTION));
+ fields[i].setType(InputField.REFERENCE);
+ fields[i].setHidden(true);
+ } else {
+
+ fields[i].setHelpReference("xxxhelp");
+ final ObjectAdapter[] optionsForParameter = action.getChoices(object)[i];
+ FieldFactory.initializeField(context, object, param, optionsForParameter, !param.isOptional(), field);
+ }
+ }
+ }
+
+ /**
+ * Sets up the fields with their initial values
+ *
+ * @param showIcon
+ */
+ private static void setDefaults(final Request context, final ObjectAdapter object, final ObjectAction action, final InputField[] fields, final FormState entryState, final boolean showIcon) {
+ final ObjectAdapter[] defaultValues = action.getDefaults(object);
+ if (defaultValues == null) {
+ return;
+ }
+
+ for (int i = 0; i < fields.length; i++) {
+ final InputField field = fields[i];
+ final ObjectAdapter defaultValue = defaultValues[i];
+
+ final String title = defaultValue == null ? "" : defaultValue.titleString();
+ if (field.getType() == InputField.REFERENCE) {
+ final ObjectSpecification objectSpecification = action.getParameters().get(i).getSpecification();
+ if (defaultValue != null) {
+ final String imageSegment = showIcon ? "<img class=\"small-icon\" src=\"" + context.imagePath(objectSpecification) + "\" alt=\"" + objectSpecification.getShortIdentifier() + "\"/>" : "";
+ final String html = imageSegment + title;
+ final String value = context.mapObject(defaultValue, Scope.INTERACTION);
+ field.setValue(value);
+ field.setHtml(html);
+ }
+ } else {
+ field.setValue(title);
+ }
+ }
+ }
+
+ private static void copyEntryState(final Request context, final ObjectAdapter object, final ObjectAction action, final InputField[] fields, final FormState entryState) {
+
+ for (final InputField field : fields) {
+ final FieldEditState fieldState = entryState.getField(field.getName());
+ if (fieldState != null) {
+ if (field.isEditable()) {
+ String entry;
+ entry = fieldState.getEntry();
+ field.setValue(entry);
+ }
+
+ field.setErrorText(fieldState.getError());
+ }
+ }
+ }
+
+ private static void overrideWithHtml(final Request context, final FormFieldBlock containedBlock, final InputField[] formFields) {
+ for (int i = 0; i < formFields.length; i++) {
+ final String id = ActionAction.parameterName(i);
+ if (containedBlock.hasContent(id)) {
+ final String content = containedBlock.getContent(id);
+ if (content != null) {
+ formFields[i].setHtml(content);
+ formFields[i].setType(InputField.HTML);
+ }
+ }
+ }
+ }
+
+ public ActionFormAbstract() {
+ super();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/CreateFormParameter.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/CreateFormParameter.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/CreateFormParameter.java
new file mode 100644
index 0000000..d4d02f0
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/CreateFormParameter.java
@@ -0,0 +1,43 @@
+/*
+ * 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.scimpi.dispatcher.view.form;
+
+public class CreateFormParameter {
+ public String methodName;
+ public String forwardResultTo;
+ public String forwardVoidTo;
+ public String forwardErrorTo;
+ public String buttonTitle;
+ public String formTitle;
+ public String formId;
+ public String resultName;
+ public String scope;
+ public String objectId;
+ public String description;
+ public String helpReference;
+ public String className;
+ public String id;
+ public String resultOverride;
+ public boolean showMessage;
+ public boolean showIcon;
+ public String completionMessage;
+ public String cancelTo;
+ public String labelDelimiter;
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/EditFormAbstract.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/EditFormAbstract.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/EditFormAbstract.java
new file mode 100644
index 0000000..096b8f9
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/EditFormAbstract.java
@@ -0,0 +1,171 @@
+package org.apache.isis.viewer.scimpi.dispatcher.view.form;
+
+import java.util.List;
+
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.core.metamodel.facets.object.parseable.ParseableFacet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.progmodel.facets.object.choices.enums.EnumFacet;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.scimpi.dispatcher.context.Request;
+import org.apache.isis.viewer.scimpi.dispatcher.context.Request.Scope;
+import org.apache.isis.viewer.scimpi.dispatcher.form.FieldEditState;
+import org.apache.isis.viewer.scimpi.dispatcher.form.FormState;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
+
+
+//TODO combine the common stuff that is found here and in ActionFormAbstract and LoginFormAbstract
+public abstract class EditFormAbstract extends AbstractElementProcessor {
+
+ protected final Where where = Where.OBJECT_FORMS;
+
+ public EditFormAbstract() {
+ super();
+ }
+
+ protected InputField[] createFields(final List<ObjectAssociation> fields) {
+ final InputField[] formFields = new InputField[fields.size()];
+ int length = 0;
+ for (int i = 0; i < fields.size(); i++) {
+ if (!fields.get(i).isOneToManyAssociation()) {
+ formFields[i] = new InputField(fields.get(i).getId());
+ length++;
+ }
+ }
+ final InputField[] array = new InputField[length];
+ for (int i = 0, j = 0; i < formFields.length; i++) {
+ if (formFields[i] != null) {
+ array[j++] = formFields[i];
+ }
+ }
+ return array;
+ }
+
+ protected void initializeFields(final Request context, final ObjectAdapter object, final InputField[] formFields, final FormState entryState, final boolean includeUnusableFields) {
+ for (final InputField formField : formFields) {
+ final String fieldId = formField.getName();
+ final ObjectAssociation field = object.getSpecification().getAssociation(fieldId);
+ final AuthenticationSession session = IsisContext.getAuthenticationSession();
+ final Consent usable = field.isUsable(session, object, where);
+ final ObjectAdapter[] options = field.getChoices(object);
+ FieldFactory.initializeField(context, object, field, options, field.isMandatory(), formField);
+
+ final boolean isEditable = usable.isAllowed();
+ if (!isEditable) {
+ formField.setDescription(usable.getReason());
+ }
+ formField.setEditable(isEditable);
+ final boolean hiddenField = field.isVisible(session, object, where).isVetoed();
+ final boolean unusable = usable.isVetoed();
+ final boolean hideAsUnusable = unusable && !includeUnusableFields;
+ if (hiddenField || hideAsUnusable) {
+ formField.setHidden(true);
+ }
+ }
+ }
+
+ protected void copyFieldContent(final Request context, final ObjectAdapter object, final InputField[] formFields, final boolean showIcon) {
+ for (final InputField inputField : formFields) {
+ final String fieldName = inputField.getName();
+ final ObjectAssociation field = object.getSpecification().getAssociation(fieldName);
+ if (field.isVisible(IsisContext.getAuthenticationSession(), object, where).isAllowed()) {
+ IsisContext.getPersistenceSession().resolveField(object, field);
+ final ObjectAdapter fieldValue = field.get(object);
+ if (inputField.isEditable()) {
+ final String value = getValue(context, fieldValue);
+ if (!value.equals("") || inputField.getValue() == null) {
+ inputField.setValue(value);
+ }
+ } else {
+ final String entry = getValue(context, fieldValue);
+ inputField.setHtml(entry);
+ inputField.setType(InputField.HTML);
+
+ }
+
+ if (field.getSpecification().getFacet(ParseableFacet.class) == null) {
+ if (fieldValue != null) {
+ final String iconSegment = showIcon ? "<img class=\"small-icon\" src=\"" + context.imagePath(field.getSpecification()) + "\" alt=\"" + field.getSpecification().getShortIdentifier() + "\"/>" : "";
+ final String entry = iconSegment + fieldValue.titleString();
+ inputField.setHtml(entry);
+ } else {
+ final String entry = "<em>none specified</em>";
+ inputField.setHtml(entry);
+ }
+ }
+ }
+ }
+ }
+
+ protected void setDefaults(final Request context, final ObjectAdapter object, final InputField[] formFields, final FormState entryState, final boolean showIcon) {
+ for (final InputField formField : formFields) {
+ final String fieldId = formField.getName();
+ final ObjectAssociation field = object.getSpecification().getAssociation(fieldId);
+ final ObjectAdapter defaultValue = field.getDefault(object);
+ if (defaultValue == null) {
+ continue;
+ }
+
+ final String title = defaultValue.titleString();
+ if (field.getSpecification().containsFacet(ParseableFacet.class)) {
+ formField.setValue(title);
+ } else if (field.isOneToOneAssociation()) {
+ final ObjectSpecification objectSpecification = field.getSpecification();
+ if (defaultValue != null) {
+ final String iconSegment = showIcon ? "<img class=\"small-icon\" src=\"" + context.imagePath(objectSpecification) + "\" alt=\"" + objectSpecification.getShortIdentifier() + "\"/>" : "";
+ final String html = iconSegment + title;
+ formField.setHtml(html);
+ final String value = defaultValue == null ? null : context.mapObject(defaultValue, Scope.INTERACTION);
+ formField.setValue(value);
+ }
+ }
+ }
+ }
+
+ protected void overrideWithHtml(final Request context, final FormFieldBlock containedBlock, final InputField[] formFields) {
+ for (final InputField formField : formFields) {
+ final String fieldId = formField.getName();
+ if (containedBlock.hasContent(fieldId)) {
+ final String content = containedBlock.getContent(fieldId);
+ if (content != null) {
+ formField.setHtml(content);
+ formField.setValue(null);
+ formField.setType(InputField.HTML);
+ }
+ }
+ }
+ }
+
+ protected void copyEntryState(final Request context, final ObjectAdapter object, final InputField[] formFields, final FormState entryState) {
+ for (final InputField formField : formFields) {
+ final String fieldId = formField.getName();
+ final ObjectAssociation field = object.getSpecification().getAssociation(fieldId);
+ if (field.isVisible(IsisContext.getAuthenticationSession(), object, where).isAllowed() && formField.isEditable()) {
+ final FieldEditState fieldState = entryState.getField(field.getId());
+ final String entry = fieldState == null ? "" : fieldState.getEntry();
+ formField.setValue(entry);
+ final String error = fieldState == null ? "" : fieldState.getError();
+ formField.setErrorText(error);
+ }
+ }
+ }
+
+ protected String getValue(final Request context, final ObjectAdapter field) {
+ if (field == null || field.isTransient()) {
+ return "";
+ }
+ final ObjectSpecification specification = field.getSpecification();
+ if (specification.containsFacet(EnumFacet.class)) {
+ return String.valueOf(field.getObject());
+ } else if (specification.getFacet(ParseableFacet.class) == null) {
+ return context.mapObject(field, Scope.INTERACTION);
+ } else {
+ return field.titleString();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/FieldFactory.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/FieldFactory.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/FieldFactory.java
new file mode 100644
index 0000000..d6470fc
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/FieldFactory.java
@@ -0,0 +1,104 @@
+/*
+ * 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.scimpi.dispatcher.view.form;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facets.help.HelpFacet;
+import org.apache.isis.core.metamodel.facets.maxlen.MaxLengthFacet;
+import org.apache.isis.core.metamodel.facets.multiline.MultiLineFacet;
+import org.apache.isis.core.metamodel.facets.object.parseable.ParseableFacet;
+import org.apache.isis.core.metamodel.facets.typicallen.TypicalLengthFacet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectFeature;
+import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
+import org.apache.isis.core.progmodel.facets.value.booleans.BooleanValueFacet;
+import org.apache.isis.core.progmodel.facets.value.password.PasswordValueFacet;
+import org.apache.isis.viewer.scimpi.dispatcher.context.Request;
+import org.apache.isis.viewer.scimpi.dispatcher.context.Request.Scope;
+
+public class FieldFactory {
+
+ public static void initializeField(final Request context, final ObjectAdapter object, final ObjectFeature param, final ObjectAdapter[] optionsForParameter, final boolean isRequired, final InputField field) {
+
+ field.setLabel(param.getName());
+ field.setDescription(param.getDescription());
+ field.setDataType(param.getSpecification().getShortIdentifier());
+ if (param instanceof ObjectMember) {
+ field.setHelpReference(((ObjectMember) param).getHelp());
+ } else {
+ final HelpFacet helpFacet = param.getFacet(HelpFacet.class);
+ final String value = helpFacet.value();
+ field.setHelpReference(value);
+ }
+ field.setRequired(isRequired);
+ field.setHidden(false);
+
+ if (param.getSpecification().getFacet(ParseableFacet.class) != null) {
+ final int maxLength = param.getFacet(MaxLengthFacet.class).value();
+ field.setMaxLength(maxLength);
+
+ final TypicalLengthFacet typicalLengthFacet = param.getFacet(TypicalLengthFacet.class);
+ if (typicalLengthFacet.isDerived() && maxLength > 0) {
+ field.setWidth(maxLength);
+ } else {
+ field.setWidth(typicalLengthFacet.value());
+ }
+
+ final MultiLineFacet multiLineFacet = param.getFacet(MultiLineFacet.class);
+ field.setHeight(multiLineFacet.numberOfLines());
+ field.setWrapped(!multiLineFacet.preventWrapping());
+
+ final ObjectSpecification spec = param.getSpecification();
+ if (spec.containsFacet(BooleanValueFacet.class)) {
+ field.setType(InputField.CHECKBOX);
+ } else if (spec.containsFacet(PasswordValueFacet.class)) {
+ field.setType(InputField.PASSWORD);
+ } else {
+ field.setType(InputField.TEXT);
+ }
+
+ } else {
+ field.setType(InputField.REFERENCE);
+ }
+
+ if (optionsForParameter != null) {
+ final int noOptions = optionsForParameter.length;
+ final String[] optionValues = new String[noOptions];
+ final String[] optionTitles = new String[noOptions];
+ for (int j = 0; j < optionsForParameter.length; j++) {
+ final int i = j; // + (field.isRequired() ? 0 : 1);
+ optionValues[i] = getValue(context, optionsForParameter[j]);
+ optionTitles[i] = optionsForParameter[j].titleString();
+ }
+ field.setOptions(optionTitles, optionValues);
+ }
+ }
+
+ private static String getValue(final Request context, final ObjectAdapter field) {
+ if (field == null) {
+ return "";
+ }
+ if (field.getSpecification().getFacet(ParseableFacet.class) == null) {
+ return context.mapObject(field, Scope.INTERACTION);
+ } else {
+ return field.getObject().toString();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/FormEntry.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/FormEntry.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/FormEntry.java
new file mode 100644
index 0000000..f196f7d
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/FormEntry.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.scimpi.dispatcher.view.form;
+
+import org.apache.isis.viewer.scimpi.dispatcher.context.RequestState;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
+
+public class FormEntry extends AbstractElementProcessor {
+
+ @Override
+ public void process(final TemplateProcessor templateProcessor, RequestState state) {
+ final FormFieldBlock block = (FormFieldBlock) templateProcessor.peekBlock();
+ final String field = templateProcessor.getRequiredProperty(FIELD);
+ final String value = templateProcessor.getRequiredProperty(VALUE);
+ final boolean isHidden = templateProcessor.isRequested(HIDDEN, true);
+ block.exclude(field);
+ // TODO this is replaced because the field is marked as hidden!
+ final String content = "reference <input type=\"" + (isHidden ? "hidden" : "text") + "\" disabled=\"disabled\" name=\"" + field + "\" value=\"" + value + "\" />";
+ block.replaceContent(field, content);
+ }
+
+ @Override
+ public String getName() {
+ return "form-entry";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/FormField.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/FormField.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/FormField.java
new file mode 100644
index 0000000..4409897
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/FormField.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.scimpi.dispatcher.view.form;
+
+import org.apache.isis.viewer.scimpi.dispatcher.context.RequestState;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
+
+public class FormField extends AbstractElementProcessor {
+
+ @Override
+ public void process(final TemplateProcessor templateProcessor, RequestState state) {
+ final FormFieldBlock block = (FormFieldBlock) templateProcessor.peekBlock();
+ final String field = templateProcessor.getRequiredProperty(FIELD);
+ if (block.isVisible(field)) {
+ templateProcessor.pushNewBuffer();
+ templateProcessor.processUtilCloseTag();
+ final String content = templateProcessor.popBuffer();
+ block.replaceContent(field, content);
+ }
+ }
+
+ @Override
+ public String getName() {
+ return "form-field";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/FormFieldBlock.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/FormFieldBlock.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/FormFieldBlock.java
new file mode 100644
index 0000000..9247eb0
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/FormFieldBlock.java
@@ -0,0 +1,67 @@
+/*
+ * 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.scimpi.dispatcher.view.form;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.viewer.scimpi.dispatcher.view.determine.InclusionList;
+
+public class FormFieldBlock extends InclusionList {
+ private final Map<String, String> content = new HashMap<String, String>();
+ private final Map<String, String> values = new HashMap<String, String>();
+
+ public void replaceContent(final String field, final String htmlString) {
+ content.put(field, htmlString);
+ }
+
+ public boolean hasContent(final String name) {
+ return content.containsKey(name);
+ }
+
+ public String getContent(final String name) {
+ return content.get(name);
+ }
+
+ public boolean isVisible(final String name) {
+ return true;
+ }
+
+ public boolean isNullable(final String name) {
+ return true;
+ }
+
+ public ObjectAdapter getCurrent(final String name) {
+ return null;
+ }
+
+ public void value(final String field, final String value) {
+ values.put(field, value);
+ }
+
+ public void setUpValues(final InputField[] inputFields) {
+ for (final InputField inputField : inputFields) {
+ final String name = inputField.getName();
+ inputField.setValue(values.get(name));
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/HiddenField.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/HiddenField.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/HiddenField.java
new file mode 100644
index 0000000..d03b4e3
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/HiddenField.java
@@ -0,0 +1,49 @@
+/*
+ * 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.scimpi.dispatcher.view.form;
+
+import org.apache.isis.viewer.scimpi.dispatcher.context.RequestState;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.BlockContent;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TagOrderException;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
+
+public class HiddenField extends AbstractElementProcessor {
+
+ @Override
+ public void process(final TemplateProcessor templateProcessor, RequestState state) {
+ final BlockContent blockContent = templateProcessor.peekBlock();
+ if (!(blockContent instanceof FormFieldBlock)) {
+ throw new TagOrderException(templateProcessor);
+ }
+
+ final String field = templateProcessor.getOptionalProperty("name");
+ final String value = templateProcessor.getRequiredProperty("value");
+ final FormFieldBlock block = (FormFieldBlock) blockContent;
+ block.value(field, value);
+ block.exclude(field);
+ }
+
+ @Override
+ public String getName() {
+ return "hidden-field";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/HtmlFormBuilder.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/HtmlFormBuilder.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/HtmlFormBuilder.java
index 6d362a6..3272a3e 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/HtmlFormBuilder.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/HtmlFormBuilder.java
@@ -20,13 +20,14 @@
package org.apache.isis.viewer.scimpi.dispatcher.view.form;
import org.apache.isis.core.commons.exceptions.UnknownTypeException;
-import org.apache.isis.viewer.scimpi.dispatcher.processor.TagProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.HtmlEncoder;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
import org.apache.isis.viewer.scimpi.dispatcher.view.other.HelpLink;
public class HtmlFormBuilder {
public static void createForm(
- final TagProcessor tagProcessor,
+ final TemplateProcessor templateProcessor,
final String action,
final HiddenInputField[] hiddenFields,
final InputField[] fields,
@@ -41,12 +42,12 @@ public class HtmlFormBuilder {
final String cancelTo) {
String classSegment = " class=\"" + className + (id == null ? "\"" : "\" id=\"" + id + "\"");
- tagProcessor.appendHtml("<form " + classSegment + " action=\"" + action + "\" method=\"post\" accept-charset=\"UTF-8\">\n");
+ templateProcessor.appendHtml("<form " + classSegment + " action=\"" + action + "\" method=\"post\" accept-charset=\"UTF-8\">\n");
if (formTitle != null && formTitle.trim().length() > 0) {
classSegment = " class=\"title\"";
- tagProcessor.appendHtml("<div" + classSegment + ">");
- tagProcessor.appendAsHtmlEncoded(formTitle);
- tagProcessor.appendHtml("</div>\n");
+ templateProcessor.appendHtml("<div" + classSegment + ">");
+ templateProcessor.appendAsHtmlEncoded(formTitle);
+ templateProcessor.appendHtml("</div>\n");
}
// TODO reinstate fieldsets when we can specify them
@@ -54,54 +55,54 @@ public class HtmlFormBuilder {
final String cls = "errors";
if (errors != null) {
- tagProcessor.appendHtml("<div class=\"" + cls + "\">");
- tagProcessor.appendAsHtmlEncoded(errors);
- tagProcessor.appendHtml("</div>");
+ templateProcessor.appendHtml("<div class=\"" + cls + "\">");
+ templateProcessor.appendAsHtmlEncoded(errors);
+ templateProcessor.appendHtml("</div>");
}
for (final HiddenInputField hiddenField : hiddenFields) {
if (hiddenField == null) {
continue;
}
- tagProcessor.appendHtml(" <input type=\"hidden\" name=\"" + hiddenField.getName() + "\" value=\"");
- tagProcessor.appendAsHtmlEncoded(hiddenField.getValue());
- tagProcessor.appendHtml("\" />\n");
+ templateProcessor.appendHtml(" <input type=\"hidden\" name=\"" + hiddenField.getName() + "\" value=\"");
+ templateProcessor.appendAsHtmlEncoded(hiddenField.getValue());
+ templateProcessor.appendHtml("\" />\n");
}
- tagProcessor.appendHtml(tagProcessor.getContext().interactionFields());
+ templateProcessor.appendHtml(templateProcessor.getContext().interactionFields());
for (final InputField fld : fields) {
if (fld.isHidden()) {
- tagProcessor.appendHtml(" <input type=\"hidden\" name=\"" + fld.getName() + "\" value=\"");
- tagProcessor.appendAsHtmlEncoded(fld.getValue());
- tagProcessor.appendHtml("\" />\n");
+ templateProcessor.appendHtml(" <input type=\"hidden\" name=\"" + fld.getName() + "\" value=\"");
+ templateProcessor.appendAsHtmlEncoded(fld.getValue());
+ templateProcessor.appendHtml("\" />\n");
} else {
final String errorSegment = fld.getErrorText() == null ? "" : "<span class=\"error\">" + fld.getErrorText() + "</span>";
- final String fieldSegment = createField(fld);
+ final String fieldSegment = createField(fld, templateProcessor);
final String helpSegment = HelpLink.createHelpSegment(fld.getDescription(), fld.getHelpReference());
final String title = fld.getDescription().equals("") ? "" : " title=\"" + fld.getDescription() + "\"";
- tagProcessor.appendHtml(" <div class=\"field " + fld.getName() + "\"><label class=\"label\" " + title + ">");
- tagProcessor.appendAsHtmlEncoded(fld.getLabel());
- tagProcessor.appendHtml(labelDelimiter + "</label>" + fieldSegment + errorSegment + helpSegment + "</div>\n");
+ templateProcessor.appendHtml(" <div class=\"field " + fld.getName() + "\"><label class=\"label\" " + title + ">");
+ templateProcessor.appendAsHtmlEncoded(fld.getLabel());
+ templateProcessor.appendHtml(labelDelimiter + "</label>" + fieldSegment + errorSegment + helpSegment + "</div>\n");
}
}
- tagProcessor.appendHtml(" <input class=\"button\" type=\"submit\" value=\"");
- tagProcessor.appendAsHtmlEncoded(buttonTitle);
- tagProcessor.appendHtml("\" name=\"execute\" />\n");
- HelpLink.append(tagProcessor, description, helpReference);
+ templateProcessor.appendHtml(" <input class=\"button\" type=\"submit\" value=\"");
+ templateProcessor.appendAsHtmlEncoded(buttonTitle);
+ templateProcessor.appendHtml("\" name=\"execute\" />\n");
+ HelpLink.append(templateProcessor, description, helpReference);
// TODO alllow forms to be cancelled, returning to previous page.
// request.appendHtml(" <div class=\"action\"><a class=\"button\" href=\"reset\">Cancel</a></div>");
if (cancelTo != null) {
- tagProcessor.appendHtml(" <input class=\"button\" type=\"button\" value=\"");
- tagProcessor.appendAsHtmlEncoded("Cancel");
- tagProcessor.appendHtml("\" onclick=\"window.location = '" + cancelTo + "'\" name=\"cancel\" />\n");
+ templateProcessor.appendHtml(" <input class=\"button\" type=\"button\" value=\"");
+ templateProcessor.appendAsHtmlEncoded("Cancel");
+ templateProcessor.appendHtml("\" onclick=\"window.location = '" + cancelTo + "'\" name=\"cancel\" />\n");
}
// TODO reinstate fieldsets when we can specify them
// request.appendHtml("</fieldset>\n");
- tagProcessor.appendHtml("</form>\n");
+ templateProcessor.appendHtml("</form>\n");
}
- private static String createField(final InputField field) {
+ private static String createField(final InputField field, final HtmlEncoder htmlEncoder) {
if (field.isHidden()) {
if (field.getType() == InputField.REFERENCE) {
return createObjectField(field, "hidden");
@@ -112,18 +113,18 @@ public class HtmlFormBuilder {
if (field.getType() == InputField.HTML) {
return "<span class=\"value\">" + field.getHtml() + "</span>";
} else if (field.getOptionsText() != null) {
- return createOptions(field);
+ return createOptions(field, htmlEncoder);
} else if (field.getType() == InputField.REFERENCE) {
return createObjectField(field, "text");
} else if (field.getType() == InputField.CHECKBOX) {
- return createCheckbox(field);
+ return createCheckbox(field, htmlEncoder);
} else if (field.getType() == InputField.PASSWORD) {
- return createPasswordField(field);
+ return createPasswordField(field, htmlEncoder);
} else if (field.getType() == InputField.TEXT) {
if (field.getHeight() > 1) {
- return createTextArea(field);
+ return createTextArea(field, htmlEncoder);
} else {
- return createTextField(field);
+ return createTextField(field, htmlEncoder);
}
} else {
throw new UnknownTypeException(field.toString());
@@ -135,7 +136,7 @@ public class HtmlFormBuilder {
return field.getHtml();
}
- private static String createTextArea(final InputField field) {
+ private static String createTextArea(final InputField field, final HtmlEncoder htmlEncoder) {
final String columnsSegment = field.getWidth() == 0 ? "" : " cols=\"" + field.getWidth() / field.getHeight() + "\"";
final String rowsSegment = field.getHeight() == 0 ? "" : " rows=\"" + field.getHeight() + "\"";
final String wrapSegment = !field.isWrapped() ? "" : " wrap=\"off\"";
@@ -143,21 +144,21 @@ public class HtmlFormBuilder {
final String disabled = field.isEditable() ? "" : " disabled=\"disabled\"";
final String maxLength = field.getMaxLength() == 0 ? "" : " maxlength=\"" + field.getMaxLength() + "\"";
return "<textarea" + requiredSegment + " name=\"" + field.getName() + "\"" + columnsSegment + rowsSegment + wrapSegment
- + maxLength + disabled + ">" + TagProcessor.getEncoder().encoder(field.getValue()) + "</textarea>";
+ + maxLength + disabled + ">" + htmlEncoder.encodeHtml(field.getValue()) + "</textarea>";
}
- private static String createPasswordField(final InputField field) {
+ private static String createPasswordField(final InputField field, final HtmlEncoder htmlEncoder) {
final String extra = " autocomplete=\"off\"";
- return createTextField(field, "password", extra);
+ return createTextField(field, "password", extra, htmlEncoder);
}
- private static String createTextField(final InputField field) {
- return createTextField(field, "text", "");
+ private static String createTextField(final InputField field, final HtmlEncoder htmlEncoder) {
+ return createTextField(field, "text", "", htmlEncoder);
}
- private static String createTextField(final InputField field, final String type, final String additionalAttributes) {
+ private static String createTextField(final InputField field, final String type, final String additionalAttributes, final HtmlEncoder htmlEncoder) {
final String value = field.getValue();
- final String valueSegment = value == null ? "" : " value=\"" + TagProcessor.getEncoder().encoder(value) + "\"";
+ final String valueSegment = value == null ? "" : " value=\"" + htmlEncoder.encodeHtml(value) + "\"";
final String lengthSegment = field.getWidth() == 0 ? "" : " size=\"" + field.getWidth() + "\"";
final String maxLengthSegment = field.getMaxLength() == 0 ? "" : " maxlength=\"" + field.getMaxLength() + "\"";
final String requiredSegment = !field.isRequired() ? "" : " required";
@@ -166,14 +167,14 @@ public class HtmlFormBuilder {
valueSegment + lengthSegment + maxLengthSegment + disabled + additionalAttributes + " />";
}
- private static String createCheckbox(final InputField field) {
+ private static String createCheckbox(final InputField field, final HtmlEncoder htmlEncoder) {
final String entryText = field.getValue();
final String valueSegment = entryText != null && entryText.toLowerCase().equals("true") ? " checked=\"checked\"" : "";
final String disabled = field.isEditable() ? "" : " disabled=\"disabled\"";
return "<input type=\"checkbox\" name=\"" + field.getName() + "\" value=\"true\" " + valueSegment + disabled + " />";
}
- private static String createOptions(final InputField field) {
+ private static String createOptions(final InputField field, final HtmlEncoder htmlEncoder) {
final String[] options = field.getOptionsText();
final String[] ids = field.getOptionValues();
final int length = options.length;
@@ -187,7 +188,7 @@ public class HtmlFormBuilder {
if (field.getType() == InputField.TEXT && options[i].equals("__other")) {
offerOther = true;
} else {
- str.append(" <option value=\"" + TagProcessor.getEncoder().encoder(ids[i]) + "\"" + selectedSegment + ">" + TagProcessor.getEncoder().encoder(options[i]) + "</option>\n");
+ str.append(" <option value=\"" + htmlEncoder.encodeHtml(ids[i]) + "\"" + selectedSegment + ">" + htmlEncoder.encodeHtml(options[i]) + "</option>\n");
}
}
if (!field.isRequired() || length == 0) {
http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/LogonFormAbstract.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/LogonFormAbstract.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/LogonFormAbstract.java
new file mode 100644
index 0000000..cdc7dcd
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/LogonFormAbstract.java
@@ -0,0 +1,86 @@
+package org.apache.isis.viewer.scimpi.dispatcher.view.form;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.isis.viewer.scimpi.dispatcher.context.Request;
+import org.apache.isis.viewer.scimpi.dispatcher.context.Request.Scope;
+import org.apache.isis.viewer.scimpi.dispatcher.form.FieldEditState;
+import org.apache.isis.viewer.scimpi.dispatcher.form.FormState;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
+
+//TODO combine the common stuff that is found here and in ActionFormAbstract and EditFormAbstract
+public abstract class LogonFormAbstract extends AbstractElementProcessor {
+
+ public static void loginForm(final TemplateProcessor templateProcessor, final String view) {
+ final String object = templateProcessor.getOptionalProperty(OBJECT);
+ final String method = templateProcessor.getOptionalProperty(METHOD, "logon");
+ final String result = templateProcessor.getOptionalProperty(RESULT_NAME, "_user");
+ final String resultScope = templateProcessor.getOptionalProperty(SCOPE, Scope.SESSION.name());
+ final String isisUser = templateProcessor.getOptionalProperty("isis-user", "_web_default");
+ final String formId = templateProcessor.getOptionalProperty(FORM_ID, templateProcessor.nextFormId());
+ final String labelDelimiter = templateProcessor.getOptionalProperty(LABEL_DELIMITER, ":");
+
+ // TODO error if all values are not set (not if use type is not set and all others are still defaults);
+
+ if (object != null) {
+ Request context = templateProcessor.getContext();
+ context.addVariable(LOGON_OBJECT, object, Scope.SESSION);
+ context.addVariable(LOGON_METHOD, method, Scope.SESSION);
+ context.addVariable(LOGON_RESULT_NAME, result, Scope.SESSION);
+ context.addVariable(LOGON_SCOPE, resultScope, Scope.SESSION);
+ context.addVariable(PREFIX + "isis-user", isisUser, Scope.SESSION);
+ context.addVariable(LOGON_FORM_ID, formId, Scope.SESSION);
+ }
+
+ final String error = templateProcessor.getOptionalProperty(ERROR, templateProcessor.getContext().getRequestedFile());
+ final List<HiddenInputField> hiddenFields = new ArrayList<HiddenInputField>();
+ hiddenFields.add(new HiddenInputField(ERROR, error));
+ if (view != null) {
+ hiddenFields.add(new HiddenInputField(VIEW, view));
+ }
+ hiddenFields.add(new HiddenInputField("_" + FORM_ID, formId));
+
+ final FormState entryState = (FormState) templateProcessor.getContext().getVariable(ENTRY_FIELDS);
+ boolean isforThisForm = entryState != null && entryState.isForForm(formId);
+ if (entryState != null && entryState.isForForm(formId)) {
+ }
+ final InputField nameField = createdField("username", "User Name", InputField.TEXT, isforThisForm ? entryState : null);
+ final String width = templateProcessor.getOptionalProperty("width");
+ if (width != null) {
+ final int w = Integer.valueOf(width).intValue();
+ nameField.setWidth(w);
+ }
+ final InputField passwordField = createdField("password", "Password", InputField.PASSWORD, isforThisForm ? entryState : null);
+ final InputField[] fields = new InputField[] { nameField, passwordField, };
+
+ final String formTitle = templateProcessor.getOptionalProperty(FORM_TITLE);
+ final String loginButtonTitle = templateProcessor.getOptionalProperty(BUTTON_TITLE, "Log in");
+ final String className = templateProcessor.getOptionalProperty(CLASS, "login");
+ final String id = templateProcessor.getOptionalProperty(ID, "logon");
+
+ HtmlFormBuilder.createForm(templateProcessor, "logon.app", hiddenFields.toArray(new HiddenInputField[hiddenFields.size()]), fields,
+ className, id, formTitle, labelDelimiter, null, null, loginButtonTitle,
+ isforThisForm && entryState != null ? entryState.getError() : null , null);
+ }
+
+ protected static InputField createdField(final String fieldName, final String fieldLabel, final int type, final FormState entryState) {
+ final InputField nameField = new InputField(fieldName);
+ nameField.setType(type);
+ nameField.setLabel(fieldLabel);
+ if (entryState != null) {
+ final FieldEditState fieldState = entryState.getField(fieldName);
+ final String entry = fieldState == null ? "" : fieldState.getEntry();
+ nameField.setValue(entry);
+ final String error = fieldState == null ? "" : fieldState.getError();
+ nameField.setErrorText(error);
+ }
+ return nameField;
+ }
+
+ public LogonFormAbstract() {
+ super();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/RadioListField.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/RadioListField.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/RadioListField.java
new file mode 100644
index 0000000..9530834
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/RadioListField.java
@@ -0,0 +1,71 @@
+/*
+ * 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.scimpi.dispatcher.view.form;
+
+import java.util.Iterator;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
+import org.apache.isis.viewer.scimpi.dispatcher.context.Request;
+import org.apache.isis.viewer.scimpi.dispatcher.context.RequestState;
+import org.apache.isis.viewer.scimpi.dispatcher.context.Request.Scope;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
+
+public class RadioListField extends AbstractElementProcessor {
+
+ @Override
+ public void process(final TemplateProcessor templateProcessor, RequestState state) {
+ final FormFieldBlock block = (FormFieldBlock) templateProcessor.peekBlock();
+ final String field = templateProcessor.getRequiredProperty(FIELD);
+ if (block.isVisible(field)) {
+ final String id = templateProcessor.getRequiredProperty(COLLECTION);
+ final String exclude = templateProcessor.getOptionalProperty("exclude");
+
+ final ObjectAdapter collection = templateProcessor.getContext().getMappedObjectOrResult(id);
+
+ final Request context = templateProcessor.getContext();
+ final CollectionFacet facet = collection.getSpecification().getFacet(CollectionFacet.class);
+ final Iterator<ObjectAdapter> iterator = facet.iterator(collection);
+
+ final StringBuffer buffer = new StringBuffer();
+
+ while (iterator.hasNext()) {
+ final ObjectAdapter element = iterator.next();
+ final Scope scope = Scope.INTERACTION;
+ final String elementId = context.mapObject(element, scope);
+ if (exclude != null && context.getMappedObject(exclude) == element) {
+ continue;
+ }
+ final String title = element.titleString();
+ final String checked = "";
+ buffer.append("<input type=\"radio\" name=\"" + field + "\" value=\"" + elementId + "\"" + checked + " />" + title + "</input><br/>\n");
+ }
+
+ block.replaceContent(field, buffer.toString());
+ }
+ }
+
+ @Override
+ public String getName() {
+ return "radio-list";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/Selector.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/Selector.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/Selector.java
new file mode 100644
index 0000000..effe589
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/Selector.java
@@ -0,0 +1,157 @@
+/*
+ * 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.scimpi.dispatcher.view.form;
+
+import java.util.Iterator;
+
+import org.apache.isis.core.commons.exceptions.UnknownTypeException;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.viewer.scimpi.dispatcher.context.Request;
+import org.apache.isis.viewer.scimpi.dispatcher.context.RequestState;
+import org.apache.isis.viewer.scimpi.dispatcher.context.Request.Scope;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.util.MethodsUtils;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
+
+public class Selector extends AbstractElementProcessor {
+
+ @Override
+ public void process(final TemplateProcessor templateProcessor, RequestState state) {
+ final FormFieldBlock block = (FormFieldBlock) templateProcessor.peekBlock();
+ final String field = templateProcessor.getRequiredProperty(FIELD);
+ if (block.isVisible(field)) {
+ processElement(templateProcessor, block, field);
+ }
+ templateProcessor.skipUntilClose();
+ }
+
+ private void processElement(final TemplateProcessor templateProcessor, final FormFieldBlock block, final String field) {
+ final String type = templateProcessor.getOptionalProperty(TYPE, "dropdown");
+ if (!templateProcessor.isPropertySpecified(METHOD) && templateProcessor.isPropertySpecified(COLLECTION)) {
+ final String id = templateProcessor.getRequiredProperty(COLLECTION, TemplateProcessor.NO_VARIABLE_CHECKING);
+ final String selector = showSelectionList(templateProcessor, id, block.getCurrent(field), block.isNullable(field), type);
+ block.replaceContent(field, selector);
+ } else {
+ final String objectId = templateProcessor.getOptionalProperty(OBJECT);
+ final String methodName = templateProcessor.getRequiredProperty(METHOD);
+ final ObjectAdapter object = MethodsUtils.findObject(templateProcessor.getContext(), objectId);
+ final ObjectAction action = MethodsUtils.findAction(object, methodName);
+ if (action.getParameterCount() == 0) {
+ final ObjectAdapter collection = action.execute(object, new ObjectAdapter[0]);
+ final String selector = showSelectionList(templateProcessor, collection, block.getCurrent(field), block.isNullable(field), type);
+ block.replaceContent(field, selector);
+ } else {
+ final String id = "selector_options";
+ final String id2 = (String) templateProcessor.getContext().getVariable(id);
+ final String selector = showSelectionList(templateProcessor, id2, block.getCurrent(field), block.isNullable(field), type);
+
+ final CreateFormParameter parameters = new CreateFormParameter();
+ parameters.objectId = objectId;
+ parameters.methodName = methodName;
+ parameters.buttonTitle = templateProcessor.getOptionalProperty(BUTTON_TITLE, "Search");
+ parameters.formTitle = templateProcessor.getOptionalProperty(FORM_TITLE);
+ parameters.className = templateProcessor.getOptionalProperty(CLASS, "selector");
+ parameters.id = templateProcessor.getOptionalProperty(ID);
+
+ parameters.resultName = id;
+ parameters.forwardResultTo = templateProcessor.getContext().getResourceFile();
+ parameters.forwardVoidTo = "error";
+ parameters.forwardErrorTo = parameters.forwardResultTo;
+ parameters.scope = Scope.REQUEST.name();
+ templateProcessor.pushNewBuffer();
+ ActionFormAbstract.createForm(templateProcessor, parameters);
+ block.replaceContent(field, selector);
+
+ templateProcessor.appendHtml(templateProcessor.popBuffer());
+ }
+ }
+ }
+
+ private String showSelectionList(final TemplateProcessor templateProcessor, final String collectionId, final ObjectAdapter selectedItem, final boolean allowNotSet, final String type) {
+ if (collectionId != null && !collectionId.equals("")) {
+ final ObjectAdapter collection = templateProcessor.getContext().getMappedObjectOrResult(collectionId);
+ return showSelectionList(templateProcessor, collection, selectedItem, allowNotSet, type);
+ } else {
+ return null;
+ }
+ }
+
+ private String showSelectionList(final TemplateProcessor templateProcessor, final ObjectAdapter collection, final ObjectAdapter selectedItem, final boolean allowNotSet, final String type) {
+ final String field = templateProcessor.getRequiredProperty(FIELD);
+ final CollectionFacet facet = collection.getSpecification().getFacet(CollectionFacet.class);
+
+ if (type.equals("radio")) {
+ return radioButtonList(templateProcessor, field, allowNotSet, collection, selectedItem, facet);
+ } else if (type.equals("list")) {
+ final String size = templateProcessor.getOptionalProperty("size", "5");
+ return dropdownList(templateProcessor, field, allowNotSet, collection, selectedItem, size, facet);
+ } else if (type.equals("dropdown")) {
+ return dropdownList(templateProcessor, field, allowNotSet, collection, selectedItem, null, facet);
+ } else {
+ throw new UnknownTypeException(type);
+ }
+ }
+
+ private String radioButtonList(final TemplateProcessor templateProcessor, final String field, final boolean allowNotSet, final ObjectAdapter collection, final ObjectAdapter selectedItem, final CollectionFacet facet) {
+ final Request context = templateProcessor.getContext();
+ final Iterator<ObjectAdapter> iterator = facet.iterator(collection);
+ final StringBuffer buffer = new StringBuffer();
+ if (allowNotSet) {
+ buffer.append("<input type=\"radio\" name=\"" + field + "\" value=\"null\"></input><br/>\n");
+ }
+ while (iterator.hasNext()) {
+ final ObjectAdapter element = iterator.next();
+ final String elementId = context.mapObject(element, Scope.INTERACTION);
+ final String title = element.titleString();
+ final String checked = element == selectedItem ? "checked=\"checked\"" : "";
+ buffer.append("<input type=\"radio\" name=\"" + field + "\" value=\"" + elementId + "\"" + checked + ">" + title + "</input><br/>\n");
+ }
+
+ return buffer.toString();
+ }
+
+ private String dropdownList(final TemplateProcessor templateProcessor, final String field, final boolean allowNotSet, final ObjectAdapter collection, final ObjectAdapter selectedItem, String size, final CollectionFacet facet) {
+ final Request context = templateProcessor.getContext();
+ final Iterator<ObjectAdapter> iterator = facet.iterator(collection);
+ final StringBuffer buffer = new StringBuffer();
+ size = size == null ? "" : " size =\"" + size + "\"";
+ buffer.append("<select name=\"" + field + "\"" + size + " >\n");
+ if (allowNotSet) {
+ buffer.append(" <option value=\"null\"></option>\n");
+ }
+ while (iterator.hasNext()) {
+ final ObjectAdapter element = iterator.next();
+ final String elementId = context.mapObject(element, Scope.INTERACTION);
+ final String title = element.titleString();
+ final String checked = element == selectedItem ? "selected=\"selected\"" : "";
+ buffer.append(" <option value=\"" + elementId + "\"" + checked + ">" + title + "</option>\n");
+ }
+ buffer.append("</select>\n");
+ return buffer.toString();
+ }
+
+ @Override
+ public String getName() {
+ return "selector";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/SimpleButton.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/SimpleButton.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/SimpleButton.java
new file mode 100644
index 0000000..1a16dde
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/SimpleButton.java
@@ -0,0 +1,40 @@
+/*
+ * 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.scimpi.dispatcher.view.form;
+
+import org.apache.isis.viewer.scimpi.dispatcher.context.RequestState;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
+
+public class SimpleButton extends AbstractElementProcessor {
+ @Override
+ public void process(final TemplateProcessor templateProcessor, RequestState state) {
+ final String href = templateProcessor.getRequiredProperty("href");
+ templateProcessor.pushNewBuffer();
+ templateProcessor.processUtilCloseTag();
+ final String text = templateProcessor.popBuffer();
+ templateProcessor.appendHtml("<div class=\"action\"><a class=\"button\" href=\"" + href + "\">" + text + "</a></div>");
+ }
+
+ @Override
+ public String getName() {
+ return "button";
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/global/Commit.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/global/Commit.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/global/Commit.java
new file mode 100644
index 0000000..f9375f5
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/global/Commit.java
@@ -0,0 +1,46 @@
+/*
+ * 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.scimpi.dispatcher.view.global;
+
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
+import org.apache.isis.viewer.scimpi.dispatcher.context.RequestState;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
+
+public class Commit extends AbstractElementProcessor {
+
+ @Override
+ public String getName() {
+ return "commit";
+ }
+
+ @Override
+ public void process(final TemplateProcessor templateProcessor, RequestState state) {
+ // Note - the session will have changed since the earlier call if a user
+ // has logged in or out in the action
+ // processing above.
+ final IsisTransactionManager transactionManager = IsisContext.getPersistenceSession().getTransactionManager();
+ if (transactionManager.getTransaction().getState().canCommit()) {
+ transactionManager.endTransaction();
+ transactionManager.startTransaction();
+ }
+ }
+
+}