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:12 UTC

[15/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/object/FieldValue.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/FieldValue.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/FieldValue.java
new file mode 100644
index 0000000..fda2559
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/FieldValue.java
@@ -0,0 +1,119 @@
+/*
+ *  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.object;
+
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+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.value.booleans.BooleanValueFacet;
+import org.apache.isis.core.runtime.persistence.ObjectNotFoundException;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.scimpi.ForbiddenException;
+import org.apache.isis.viewer.scimpi.ScimpiException;
+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;
+import org.apache.isis.viewer.scimpi.dispatcher.view.determine.LinkedObject;
+
+public class FieldValue extends AbstractElementProcessor {
+
+    // REVIEW: should provide this rendering context, rather than hardcoding.
+    // the net effect currently is that class members annotated with 
+    // @Hidden(where=Where.ANYWHERE) or @Disabled(where=Where.ANYWHERE) will indeed
+    // be hidden/disabled, but will be visible/enabled (perhaps incorrectly) 
+    // for any other value for Where
+    private final Where where = Where.ANYWHERE;
+
+    @Override
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
+        final String className = templateProcessor.getOptionalProperty(CLASS);
+        final String id = templateProcessor.getOptionalProperty(OBJECT);
+        final String fieldName = templateProcessor.getRequiredProperty(FIELD);
+        final ObjectAdapter object = templateProcessor.getContext().getMappedObjectOrResult(id);
+        final ObjectAssociation field = object.getSpecification().getAssociation(fieldName);
+        if (field == null) {
+            throw new ScimpiException("No field " + fieldName + " in " + object.getSpecification().getFullIdentifier());
+        }
+        if (field.isVisible(IsisContext.getAuthenticationSession(), object, where).isVetoed()) {
+            throw new ForbiddenException(field, ForbiddenException.VISIBLE);
+        }
+        final boolean isIconShowing = templateProcessor.isRequested(SHOW_ICON, showIconByDefault());
+        final int truncateTo = Integer.valueOf(templateProcessor.getOptionalProperty(TRUNCATE, "0")).intValue();
+
+        write(templateProcessor, object, field, null, className, isIconShowing, truncateTo);
+    }
+
+    @Override
+    public String getName() {
+        return "field";
+    }
+
+    public static void write(final TemplateProcessor templateProcessor, final ObjectAdapter object, final ObjectAssociation field, final LinkedObject linkedField, final String className, final boolean showIcon, final int truncateTo) {
+
+        final ObjectAdapter fieldReference = field.get(object);
+
+        if (fieldReference != null) {
+            final String classSection = "class=\"" + (className == null ? "value" : className) + "\"";
+            templateProcessor.appendHtml("<span " + classSection + ">");
+            if (field.isOneToOneAssociation()) {
+                try {
+                    IsisContext.getPersistenceSession().resolveImmediately(fieldReference);
+                } catch (final ObjectNotFoundException e) {
+                    templateProcessor.appendHtml(e.getMessage() + "</span>");
+                }
+            }
+
+            if (!field.getSpecification().containsFacet(ParseableFacet.class) && showIcon) {
+                templateProcessor.appendHtml("<img class=\"small-icon\" src=\"" + templateProcessor.getContext().imagePath(fieldReference) + "\" alt=\"" + field.getSpecification().getShortIdentifier() + "\"/>");
+            }
+
+            if (linkedField != null) {
+                final String id = templateProcessor.getContext().mapObject(fieldReference, linkedField.getScope(), Scope.INTERACTION);
+                templateProcessor.appendHtml("<a href=\"" + linkedField.getForwardView() + "?" + linkedField.getVariable() + "=" + id + templateProcessor.getContext().encodedInteractionParameters() + "\">");
+            }
+            String value = fieldReference == null ? "" : fieldReference.titleString();
+            if (truncateTo > 0 && value.length() > truncateTo) {
+                value = value.substring(0, truncateTo) + "...";
+            }
+
+            // TODO figure out a better way to determine if boolean or a
+            // password
+            final ObjectSpecification spec = field.getSpecification();
+            final BooleanValueFacet facet = spec.getFacet(BooleanValueFacet.class);
+            if (facet != null) {
+                final boolean flag = facet.isSet(fieldReference);
+                final String valueSegment = flag ? " checked=\"checked\"" : "";
+                final String disabled = " disabled=\"disabled\"";
+                templateProcessor.appendHtml("<input type=\"checkbox\"" + valueSegment + disabled + " />");
+            } else {
+                templateProcessor.appendAsHtmlEncoded(value);
+            }
+
+            if (linkedField != null) {
+                templateProcessor.appendHtml("</a>");
+            }
+            templateProcessor.appendHtml("</span>");
+        }
+    }
+
+}

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/object/GetField.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/GetField.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/GetField.java
new file mode 100644
index 0000000..25b2fa0
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/GetField.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.object;
+
+import java.text.DecimalFormat;
+import java.text.Format;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+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.spec.feature.ObjectAssociation;
+import org.apache.isis.core.progmodel.facets.value.date.DateValueFacet;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.scimpi.ForbiddenException;
+import org.apache.isis.viewer.scimpi.ScimpiException;
+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 GetField extends AbstractElementProcessor {
+
+    // REVIEW: should provide this rendering context, rather than hardcoding.
+    // the net effect currently is that class members annotated with 
+    // @Hidden(where=Where.ANYWHERE) or @Disabled(where=Where.ANYWHERE) will indeed
+    // be hidden/disabled, but will be visible/enabled (perhaps incorrectly) 
+    // for any other value for Where
+    private final Where where = Where.ANYWHERE;
+
+    @Override
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
+        final String id = templateProcessor.getOptionalProperty(OBJECT);
+        final String fieldName = templateProcessor.getRequiredProperty(FIELD);
+        final ObjectAdapter object = templateProcessor.getContext().getMappedObjectOrResult(id);
+        if (object == null) {
+            throw new ScimpiException("No object to get field for: " + fieldName + " - " + id);
+        }
+        final ObjectAssociation field = object.getSpecification().getAssociation(fieldName);
+        if (field == null) {
+            throw new ScimpiException("No field " + fieldName + " in " + object.getSpecification().getFullIdentifier());
+        }
+        final AuthenticationSession session = IsisContext.getAuthenticationSession();
+        if (field.isVisible(session, object, where).isVetoed()) {
+            throw new ForbiddenException(field, ForbiddenException.VISIBLE);
+        }
+
+        String pattern = templateProcessor.getOptionalProperty("decimal-format");
+        Format format = null;
+        if (pattern != null) {
+            format = new DecimalFormat(pattern);
+        }
+        pattern = templateProcessor.getOptionalProperty("date-format");
+        if (pattern != null) {
+            format = new SimpleDateFormat(pattern);
+        }
+
+        final String name = templateProcessor.getOptionalProperty(RESULT_NAME, fieldName);
+        final String scopeName = templateProcessor.getOptionalProperty(SCOPE);
+        final Scope scope = Request.scope(scopeName, Scope.REQUEST);
+
+        process(templateProcessor, object, field, format, name, scope);
+    }
+
+    protected void process(final TemplateProcessor templateProcessor, final ObjectAdapter object, final ObjectAssociation field, final Format format, final String name, final Scope scope) {
+        final ObjectAdapter fieldReference = field.get(object);
+        if (format != null && fieldReference.isValue()) {
+            final DateValueFacet facet = fieldReference.getSpecification().getFacet(DateValueFacet.class);
+            final Date date = facet.dateValue(fieldReference);
+            final String value = format.format(date);
+            templateProcessor.appendDebug("    " + object + " -> " + value);
+            templateProcessor.getContext().addVariable(name, templateProcessor.encodeHtml(value), scope);
+        } else {
+            final String source = fieldReference == null ? "" : templateProcessor.getContext().mapObject(fieldReference, scope);
+            templateProcessor.appendDebug("    " + object + " -> " + source);
+            templateProcessor.getContext().addVariable(name, source, scope);
+        }
+    }
+
+    @Override
+    public String getName() {
+        return "get-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/object/IncludeObject.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/IncludeObject.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/IncludeObject.java
new file mode 100644
index 0000000..ff322bb
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/IncludeObject.java
@@ -0,0 +1,108 @@
+/*
+ *  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.object;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.scimpi.ForbiddenException;
+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;
+
+/**
+ * Element to include another file that will display an object.
+ */
+public class IncludeObject extends AbstractElementProcessor {
+
+    // REVIEW: should provide this rendering context, rather than hardcoding.
+    // the net effect currently is that class members annotated with 
+    // @Hidden(where=Where.ANYWHERE) or @Disabled(where=Where.ANYWHERE) will indeed
+    // be hidden/disabled, but will be visible/enabled (perhaps incorrectly) 
+    // for any other value for Where
+    private final Where where = Where.ANYWHERE;
+
+    @Override
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
+        final String path = templateProcessor.getOptionalProperty("file");
+        String id = templateProcessor.getOptionalProperty(OBJECT);
+        final String fieldName = templateProcessor.getOptionalProperty(FIELD);
+        ObjectAdapter object = templateProcessor.getContext().getMappedObjectOrResult(id);
+        if (fieldName != null) {
+            final ObjectAssociation field = object.getSpecification().getAssociation(fieldName);
+            if (field.isVisible(IsisContext.getAuthenticationSession(), object, where).isVetoed()) {
+                throw new ForbiddenException(field, ForbiddenException.VISIBLE);
+            }
+            object = field.get(object);
+            id = templateProcessor.getContext().mapObject(object, Scope.REQUEST);
+        }
+
+        if (object != null) {
+            IsisContext.getPersistenceSession().resolveImmediately(object);
+            templateProcessor.getContext().addVariable("_object", id, Scope.REQUEST);
+            importFile(templateProcessor, path);
+        }
+        templateProcessor.closeEmpty();
+    }
+
+    private static void importFile(final TemplateProcessor templateProcessor, final String path) {
+        // TODO load in file via HtmlFileParser
+        final File file = new File(path);
+        BufferedReader reader = null;
+        try {
+            if (file.exists()) {
+                reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
+                String line;
+                while ((line = reader.readLine()) != null) {
+                    templateProcessor.appendHtml(line);
+                }
+            } else {
+                templateProcessor.appendHtml("<P classs=\"error\">File " + path + " not found to import</P>");
+            }
+        } catch (final FileNotFoundException e) {
+            throw new RuntimeException(e);
+        } catch (final IOException e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (reader != null) {
+                try {
+                    reader.close();
+                } catch (final IOException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+    }
+
+    @Override
+    public String getName() {
+        return "include-object";
+    }
+
+}

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/object/LinkAbstract.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/LinkAbstract.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/LinkAbstract.java
new file mode 100644
index 0000000..0356e48
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/LinkAbstract.java
@@ -0,0 +1,122 @@
+/*
+ *  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.object;
+
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.scimpi.ForbiddenException;
+import org.apache.isis.viewer.scimpi.Names;
+import org.apache.isis.viewer.scimpi.ScimpiException;
+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 abstract class LinkAbstract extends AbstractElementProcessor {
+
+    @Override
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
+        final String title = templateProcessor.getOptionalProperty(FORM_TITLE);
+        final String name = templateProcessor.getOptionalProperty(NAME);
+        final boolean showAsButton = templateProcessor.isRequested("show-as-button", false);
+        final String linkClass = templateProcessor.getOptionalProperty(CLASS, showAsButton ? "button" : defaultLinkClass());
+        final String containerClass = templateProcessor.getOptionalProperty(CONTAINER_CLASS, "action");
+        final String object = templateProcessor.getOptionalProperty(OBJECT);
+        final Request context = templateProcessor.getContext();
+        String objectId = object != null ? object : (String) context.getVariable(Names.RESULT);
+        ObjectAdapter adapter = MethodsUtils.findObject(context, objectId);
+
+        // REVIEW this is common used code
+        final String fieldName = templateProcessor.getOptionalProperty(FIELD);
+        if (fieldName != null) {
+            final ObjectAssociation field = adapter.getSpecification().getAssociation(fieldName);
+            if (field == null) {
+                throw new ScimpiException("No field " + fieldName + " in " + adapter.getSpecification().getFullIdentifier());
+            }
+            
+            // REVIEW: should provide this rendering context, rather than hardcoding.
+            // the net effect currently is that class members annotated with 
+            // @Hidden(where=Where.ANYWHERE) or @Disabled(where=Where.ANYWHERE) will indeed
+            // be hidden/disabled, but will be visible/enabled (perhaps incorrectly) 
+            // for any other value for Where
+            final Where where = Where.ANYWHERE;
+            
+            if (field.isVisible(IsisContext.getAuthenticationSession(), adapter, where).isVetoed()) {
+                throw new ForbiddenException(field, ForbiddenException.VISIBLE);
+            }
+            IsisContext.getPersistenceSession().resolveField(adapter, field);
+            adapter = field.get(adapter);
+            if (adapter != null) {
+                objectId = context.mapObject(adapter, Scope.INTERACTION);
+            }
+        }
+
+        if (adapter != null && valid(templateProcessor, adapter)) {
+            final String variable = templateProcessor.getOptionalProperty("param-name", Names.RESULT);
+            final String variableSegment = variable + "=" + objectId;
+
+            String view = templateProcessor.getOptionalProperty(VIEW);
+            if (view == null) {
+                view = defaultView();
+            }
+            view = context.fullUriPath(view);
+            final String classSegment = " class=\"" + linkClass + "\"";
+            final String titleSegment = title == null ? "" : (" title=\"" + title + "\"");
+            String additionalSegment = additionalParameters(templateProcessor);
+            additionalSegment = additionalSegment == null ? "" : "&amp;" + additionalSegment;
+            if (showAsButton) {
+                templateProcessor.appendHtml("<div class=\"" + containerClass + "\">");
+            }
+            templateProcessor.appendHtml("<a" + classSegment + titleSegment + " href=\"" + view + "?" + variableSegment + context.encodedInteractionParameters() + additionalSegment + "\">");
+            templateProcessor.pushNewBuffer();
+            templateProcessor.processUtilCloseTag();
+            final String buffer = templateProcessor.popBuffer();
+            if (buffer.trim().length() > 0) {
+                templateProcessor.appendHtml(buffer);
+            } else {
+                templateProcessor.appendAsHtmlEncoded(linkLabel(name, adapter));
+            }
+            templateProcessor.appendHtml("</a>");
+            if (showAsButton) {
+                templateProcessor.appendHtml("</div>");
+            }
+        } else {
+            templateProcessor.skipUntilClose();
+        }
+    }
+
+    private String defaultLinkClass() {
+        return "action";
+    }
+
+    protected abstract String linkLabel(String name, ObjectAdapter object);
+
+    protected String additionalParameters(final TemplateProcessor templateProcessor) {
+        return null;
+    }
+
+    protected abstract boolean valid(TemplateProcessor templateProcessor, ObjectAdapter adapter);
+
+    protected abstract String defaultView();
+}

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/object/LongViewForm.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/LongViewForm.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/LongViewForm.java
new file mode 100644
index 0000000..ac2678b
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/LongViewForm.java
@@ -0,0 +1,87 @@
+/*
+ *  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.object;
+
+import java.util.List;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociationFilters;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.view.collection.TableContentWriter;
+import org.apache.isis.viewer.scimpi.dispatcher.view.collection.TableView;
+import org.apache.isis.viewer.scimpi.dispatcher.view.collection.TableView.SimpleTableBuilder;
+import org.apache.isis.viewer.scimpi.dispatcher.view.determine.LinkedObject;
+
+public class LongViewForm extends ViewFormAbstract {
+
+    @Override
+    protected void addField(final TemplateProcessor templateProcessor, final ObjectAdapter object, final ObjectAssociation field, final LinkedObject linkedObject, final boolean showIcons) {
+        if (field.isOneToManyAssociation()) {
+            final String noColumnsString = templateProcessor.getOptionalProperty("no-columns", "3");
+            final String tableClass = templateProcessor.getOptionalProperty("table-class");
+            final String rowClassesList = templateProcessor.getOptionalProperty("row-classes", ODD_ROW_CLASS + "|" + EVEN_ROW_CLASS);
+            String[] rowClasses = new String[0];
+            if (rowClassesList != null) {
+                rowClasses = rowClassesList.split("[,|/]");
+            }
+            int noColumns;
+            IsisContext.getPersistenceSession().resolveField(object, field);
+            final ObjectAdapter collection = field.get(object);
+            final ObjectSpecification elementSpec = collection.getElementSpecification();
+            final List<ObjectAssociation> fields = elementSpec.getAssociations(ObjectAssociationFilters.WHEN_VISIBLE_IRRESPECTIVE_OF_WHERE);
+            if (noColumnsString.equalsIgnoreCase("all")) {
+                noColumns = fields.size();
+            } else {
+                noColumns = Math.min(fields.size(), Integer.valueOf(noColumnsString));
+            }
+            // final boolean isFieldEditable = field.isUsable(IsisContext.getAuthenticationSession(), object).isAllowed();
+            final String summary = "Table of elements in " + field.getName();
+            // TableView.write(request, summary, object, field, collection, noColumns, fields, isFieldEditable, showIconByDefault(), tableClass, rowClasses, linkedObject);
+            
+            
+            final String headers[] = new String[fields.size()];
+            int h = 0;
+            for (int i = 0; i < noColumns; i++) {
+                if (fields.get(i).isOneToManyAssociation()) {
+                    continue;
+                }
+                headers[h++] = fields.get(i).getName();
+            }
+            
+            final LinkedObject[] linkedFields = new LinkedObject[fields.size()];
+
+
+            final TableContentWriter rowBuilder =new SimpleTableBuilder(object.titleString(), true, false, "", noColumns, headers, fields, false,
+                    showIcons, false, false, false, field.getName(), linkedFields, null);
+            TableView.write(templateProcessor, collection, summary, rowBuilder, null, tableClass, rowClasses);
+        } else {
+            super.addField(templateProcessor, object, field, linkedObject, showIcons);
+        }
+    }
+
+    @Override
+    public String getName() {
+        return "long-form";
+    }
+
+}

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/object/ObjectLink.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/ObjectLink.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/ObjectLink.java
new file mode 100644
index 0000000..15f92d7
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/ObjectLink.java
@@ -0,0 +1,68 @@
+/*
+ *  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.object;
+
+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.spec.feature.ObjectAssociation;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociationFilters;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.scimpi.Names;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
+
+public class ObjectLink extends LinkAbstract {
+
+    // REVIEW: should provide this rendering context, rather than hardcoding.
+    // the net effect currently is that class members annotated with 
+    // @Hidden(where=Where.ANYWHERE) or @Disabled(where=Where.ANYWHERE) will indeed
+    // be hidden/disabled, but will be visible/enabled (perhaps incorrectly) 
+    // for any other value for Where
+    private final Where where = Where.ANYWHERE;
+
+    @Override
+    protected boolean valid(final TemplateProcessor templateProcessor, final ObjectAdapter object) {
+        final AuthenticationSession session = IsisContext.getAuthenticationSession();
+        final List<ObjectAssociation> visibleFields = object.getSpecification().getAssociations(ObjectAssociationFilters.dynamicallyVisible(session, object, where));
+        return visibleFields.size() > 0;
+    }
+
+    @Override
+    protected String linkLabel(final String name, final ObjectAdapter object) {
+        if (name == null) {
+            return object.titleString();
+        } else {
+            return name;
+        }
+    }
+
+    @Override
+    protected String defaultView() {
+        return Names.GENERIC + "." + Names.EXTENSION;
+    }
+
+    @Override
+    public String getName() {
+        return "object-link";
+    }
+
+}

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/object/SelectedObject.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/SelectedObject.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/SelectedObject.java
new file mode 100644
index 0000000..ec4c321
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/SelectedObject.java
@@ -0,0 +1,56 @@
+/*
+ *  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.object;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+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;
+
+/**
+ * <swf:selected name="selected" object="${action}" equals="${subaction}" />
+ */
+public class SelectedObject extends AbstractElementProcessor {
+
+    @Override
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
+        final String name = templateProcessor.getOptionalProperty(NAME, "selected");
+        final String objectId = templateProcessor.getRequiredProperty(OBJECT);
+        final String equalsId = templateProcessor.getOptionalProperty("equals");
+        final String title = templateProcessor.getOptionalProperty(BUTTON_TITLE);
+
+        final ObjectAdapter object = templateProcessor.getContext().getMappedObjectOrResult(objectId);
+        final ObjectAdapter other = templateProcessor.getContext().getMappedObjectOrResult(equalsId);
+        if (object == other || object.equals(title)) {
+            // TODO title is not being used!
+            templateProcessor.getContext().addVariable(ID, " id=\"" + name + "\" ", Scope.INTERACTION);
+        } else {
+            templateProcessor.getContext().addVariable(ID, "", Scope.INTERACTION);
+        }
+        templateProcessor.closeEmpty();
+    }
+
+    @Override
+    public String getName() {
+        return "selected";
+    }
+
+}

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/object/ShortViewForm.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/ShortViewForm.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/ShortViewForm.java
new file mode 100644
index 0000000..6ed7ff6
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/ShortViewForm.java
@@ -0,0 +1,36 @@
+/*
+ *  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.object;
+
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+
+public class ShortViewForm extends ViewFormAbstract {
+
+    @Override
+    protected boolean ignoreField(final ObjectAssociation field) {
+        return field.isOneToManyAssociation();
+    }
+
+    @Override
+    public String getName() {
+        return "short-form";
+    }
+
+}

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/object/Title.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/Title.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/Title.java
new file mode 100644
index 0000000..bcff697
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/Title.java
@@ -0,0 +1,69 @@
+/*
+ *  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.object;
+
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.scimpi.ForbiddenException;
+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.util.MethodsUtils;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
+
+public class Title extends AbstractElementProcessor {
+
+    @Override
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
+        final String id = templateProcessor.getOptionalProperty(OBJECT);
+        final String fieldName = templateProcessor.getOptionalProperty(FIELD);
+        final int truncateTo = Integer.valueOf(templateProcessor.getOptionalProperty(TRUNCATE, "0")).intValue();
+        final boolean isIconShowing = templateProcessor.isRequested(SHOW_ICON, showIconByDefault());
+        String className = templateProcessor.getOptionalProperty(CLASS);
+        className = className == null ? "title-icon" : className;
+        ObjectAdapter object = MethodsUtils.findObject(state, id);
+        if (fieldName != null) {
+            final ObjectAssociation field = object.getSpecification().getAssociation(fieldName);
+            if (field.isVisible(IsisContext.getAuthenticationSession(), object, Where.ANYWHERE).isVetoed()) {
+                throw new ForbiddenException(field, ForbiddenException.VISIBLE);
+            }
+            object = field.get(object);
+        }
+
+        if (object != null) {
+            templateProcessor.appendHtml("<span class=\"object title\">");
+            IsisContext.getPersistenceSession().resolveImmediately(object);
+            if (isIconShowing) {
+                final String iconPath = templateProcessor.getContext().imagePath(object);
+                templateProcessor.appendHtml("<img class=\"" + className + "\" src=\"" + iconPath + "\" />");
+            }
+            templateProcessor.appendTruncated(object.titleString(), truncateTo);
+            templateProcessor.appendHtml("</span>");
+        }
+        templateProcessor.closeEmpty();
+    }
+
+    @Override
+    public String getName() {
+        return "title";
+    }
+
+}

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/object/TitleString.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/TitleString.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/TitleString.java
new file mode 100644
index 0000000..7672281
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/TitleString.java
@@ -0,0 +1,69 @@
+/*
+ *  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.object;
+
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.scimpi.ForbiddenException;
+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 TitleString extends AbstractElementProcessor {
+
+    @Override
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
+        final String id = templateProcessor.getOptionalProperty(OBJECT);
+        final String fieldName = templateProcessor.getOptionalProperty(FIELD);
+        final int truncateTo = Integer.valueOf(templateProcessor.getOptionalProperty(TRUNCATE, "0")).intValue();
+        final ObjectAdapter object = templateProcessor.getContext().getMappedObjectOrResult(id);
+        if (object == null) { 
+            return; 
+        } 
+        String titleString;
+        if (fieldName == null) {
+            titleString = object.titleString();
+        } else {
+            final ObjectAssociation field = object.getSpecification().getAssociation(fieldName);
+            if (field.isVisible(IsisContext.getAuthenticationSession(), object, Where.ANYWHERE).isVetoed()) {
+                throw new ForbiddenException(field, ForbiddenException.VISIBLE);
+            }
+            final ObjectAdapter fieldReference = field.get(object);
+            if (fieldReference != null) {
+                titleString = fieldReference.titleString();
+            } else {
+                titleString = "";
+            }
+        }
+        templateProcessor.appendDebug("    " + titleString);
+        templateProcessor.appendTruncated(titleString, truncateTo);
+    }
+
+    @Override
+    public String getName() {
+        return "title-string";
+    }
+
+}

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/object/Type.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/Type.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/Type.java
new file mode 100644
index 0000000..bce4000
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/Type.java
@@ -0,0 +1,58 @@
+/*
+ *  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.object;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+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.processor.TemplateProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
+
+public class Type extends AbstractElementProcessor {
+
+    @Override
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
+        final Request context = templateProcessor.getContext();
+        final String showPlural = templateProcessor.getOptionalProperty(PLURAL);
+        final String id = templateProcessor.getOptionalProperty(OBJECT);
+        final String objectId = id != null ? id : (String) context.getVariable(RESULT);
+
+        ObjectAdapter object = context.getMappedObjectOrResult(objectId);
+        final String field = templateProcessor.getOptionalProperty(FIELD);
+        if (field != null) {
+            final ObjectAssociation objectField = object.getSpecification().getAssociation(field);
+            object = objectField.get(object);
+        }
+        templateProcessor.appendDebug(" for " + object);
+
+        final ObjectSpecification specification = object.getSpecification();
+        final String name = showPlural != null ? specification.getPluralName() : specification.getSingularName();
+
+        templateProcessor.appendAsHtmlEncoded(name);
+    }
+
+    @Override
+    public String getName() {
+        return "type";
+    }
+
+}

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/object/ViewFormAbstract.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/ViewFormAbstract.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/ViewFormAbstract.java
new file mode 100644
index 0000000..3d6e2f2
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/object/ViewFormAbstract.java
@@ -0,0 +1,142 @@
+/*
+ *  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.object;
+
+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.facets.object.parseable.ParseableFacet;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociationFilters;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractObjectProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.view.determine.LinkedFieldsBlock;
+import org.apache.isis.viewer.scimpi.dispatcher.view.determine.LinkedObject;
+import org.apache.isis.viewer.scimpi.dispatcher.view.other.HelpLink;
+
+public abstract class ViewFormAbstract extends AbstractObjectProcessor {
+
+    @Override
+    public String checkFieldType(final ObjectAssociation objectField) {
+        return objectField.isOneToOneAssociation() ? null : "is not an object";
+    }
+
+    @Override
+    public void process(final TemplateProcessor templateProcessor, final ObjectAdapter object) {
+        final LinkedFieldsBlock tag = new LinkedFieldsBlock();
+
+        if (object != null) {
+            final String id = templateProcessor.getOptionalProperty(ID, object.getSpecification().getShortIdentifier()); 
+            final String cls = templateProcessor.getOptionalProperty(CLASS, "form");
+            final String classString = " id=\"" + id + "\" class=\"" + cls + "\"";
+            String title = templateProcessor.getOptionalProperty(FORM_TITLE);
+            final String oddRowClass = templateProcessor.getOptionalProperty(ODD_ROW_CLASS);
+            final String evenRowClass = templateProcessor.getOptionalProperty(EVEN_ROW_CLASS);
+            final String labelDelimiter = templateProcessor.getOptionalProperty(LABEL_DELIMITER, ":");
+            final boolean showIcons = templateProcessor.isRequested(SHOW_ICON, showIconByDefault()); 
+            String linkAllView = templateProcessor.getOptionalProperty(LINK_VIEW);
+
+            templateProcessor.pushBlock(tag);
+            templateProcessor.processUtilCloseTag();
+
+            final AuthenticationSession session = IsisContext.getAuthenticationSession(); 
+            List<ObjectAssociation> associations = object.getSpecification().getAssociations(ObjectAssociationFilters.dynamicallyVisible(session, object, Where.OBJECT_FORMS));
+            final List<ObjectAssociation> fields = tag.includedFields(associations);
+            final LinkedObject[] linkFields = tag.linkedFields(fields);
+
+            if (linkAllView != null) {
+                linkAllView = templateProcessor.getContext().fullUriPath(linkAllView);
+                for (int i = 0; i < linkFields.length; i++) {
+                    final boolean isObject = fields.get(i).isOneToOneAssociation();
+                    final boolean isNotParseable = !fields.get(i).getSpecification().containsFacet(ParseableFacet.class);
+                    linkFields[i] = isObject && isNotParseable ? new LinkedObject(linkAllView) : null;
+                }
+            }
+
+            if (title == null) {
+                title = object.getSpecification().getSingularName();
+            } else if (title.equals("")) {
+                title = null;
+            }
+
+            write(templateProcessor, object, fields, linkFields, classString, title, labelDelimiter, oddRowClass, evenRowClass, showIcons);
+        } else {
+            templateProcessor.skipUntilClose(); 
+        }
+    }
+
+    private void write(
+            final TemplateProcessor templateProcessor,
+            final ObjectAdapter object,
+            final List<ObjectAssociation> fields,
+            final LinkedObject[] linkFields,
+            final String classString,
+            final String title,
+            final String labelDelimiter,
+            final String oddRowClass,
+            final String evenRowClass,
+            final boolean showIcons) {
+        templateProcessor.appendHtml("<div" + classString + ">");
+        if (title != null) {
+            templateProcessor.appendHtml("<div class=\"title\">");
+            templateProcessor.appendAsHtmlEncoded(title);
+            templateProcessor.appendHtml("</div>");
+            HelpLink.append(templateProcessor, object.getSpecification().getDescription(), object.getSpecification().getHelp());
+        }
+        int row = 1;
+        for (int i = 0; i < fields.size(); i++) {
+            final ObjectAssociation field = fields.get(i);
+            if (ignoreField(field)) {
+                continue;
+            }
+            if (field.isVisible(IsisContext.getAuthenticationSession(), object, Where.OBJECT_FORMS).isVetoed()) {
+                continue;
+            }
+
+            final String description = field.getDescription().equals("") ? "" : "title=\"" + field.getDescription() + "\"";
+            String cls;
+            if (row++ % 2 == 1) {
+                cls = " class=\"field " + (oddRowClass == null ? ODD_ROW_CLASS : oddRowClass) + "\"";
+            } else {
+                cls = " class=\"field " + (evenRowClass == null ? EVEN_ROW_CLASS : evenRowClass) + "\"";
+            }
+            templateProcessor.appendHtml("<div " + cls + description + "><span class=\"label\">");
+            templateProcessor.appendAsHtmlEncoded(field.getName());
+            templateProcessor.appendHtml(labelDelimiter + "</span>");
+            final LinkedObject linkedObject = linkFields[i];
+            addField(templateProcessor, object, field, linkedObject, showIcons);
+            HelpLink.append(templateProcessor, field.getDescription(), field.getHelp());
+            templateProcessor.appendHtml("</div>");
+        }
+        templateProcessor.appendHtml("</div>");
+    }
+
+    protected void addField(final TemplateProcessor templateProcessor, final ObjectAdapter object, final ObjectAssociation field, final LinkedObject linkedObject, final boolean showIcons) {
+        FieldValue.write(templateProcessor, object, field, linkedObject, null, showIcons, 0);
+    }
+
+    protected boolean ignoreField(final ObjectAssociation objectField) {
+        return false;
+    }
+
+}

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/other/HelpLink.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/other/HelpLink.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/other/HelpLink.java
index 9bc5987..2dab703 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/other/HelpLink.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/other/HelpLink.java
@@ -20,7 +20,8 @@ package org.apache.isis.viewer.scimpi.dispatcher.view.other;
 
 import org.apache.isis.core.commons.config.ConfigurationConstants;
 import org.apache.isis.core.runtime.system.context.IsisContext;
-import org.apache.isis.viewer.scimpi.dispatcher.processor.TagProcessor;
+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 HelpLink extends AbstractElementProcessor {
@@ -28,8 +29,8 @@ public class HelpLink extends AbstractElementProcessor {
     private static String site;
     private static String suffix;
 
-    public static void append(final TagProcessor tagProcessor, final String description, final String helpReference) {
-        tagProcessor.appendHtml(createHelpSegment(description, helpReference));
+    public static void append(final TemplateProcessor templateProcessor, final String description, final String helpReference) {
+        templateProcessor.appendHtml(createHelpSegment(description, helpReference));
     }
 
     public static String createHelpSegment(final String description, final String helpReference) {
@@ -63,10 +64,10 @@ public class HelpLink extends AbstractElementProcessor {
     }
 
     @Override
-    public void process(final TagProcessor tagProcessor) {
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
         final String description = null;
-        final String helpReference = tagProcessor.getRequiredProperty("ref");
-        append(tagProcessor, description, helpReference);
+        final String helpReference = templateProcessor.getRequiredProperty("ref");
+        append(templateProcessor, description, helpReference);
     }
 
 }

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/other/History.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/other/History.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/other/History.java
index d328921..33bfaac 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/other/History.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/other/History.java
@@ -24,8 +24,9 @@ import java.util.List;
 
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 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.TagProcessor;
+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;
 
@@ -86,20 +87,20 @@ public class History extends AbstractElementProcessor {
     }
 
     @Override
-    public void process(final TagProcessor tagProcessor) {
-        final String action = tagProcessor.getOptionalProperty("action", "display");
-        final Crumbs crumbs = getCrumbs(tagProcessor);
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
+        final String action = templateProcessor.getOptionalProperty("action", "display");
+        final Crumbs crumbs = getCrumbs(templateProcessor);
         if (action.equals("display") && crumbs != null) {
-            write(crumbs, tagProcessor);
+            write(crumbs, templateProcessor);
         } else if (action.equals("link")) {
-            final String name = tagProcessor.getRequiredProperty(NAME);
-            final String link = tagProcessor.getRequiredProperty(LINK_VIEW);
+            final String name = templateProcessor.getRequiredProperty(NAME);
+            final String link = templateProcessor.getRequiredProperty(LINK_VIEW);
             crumbs.add(name, link);
         } else if (action.equals("object")) {
-            final String id = tagProcessor.getOptionalProperty(OBJECT);
-            final ObjectAdapter object = MethodsUtils.findObject(tagProcessor.getContext(), id);
+            final String id = templateProcessor.getOptionalProperty(OBJECT);
+            final ObjectAdapter object = MethodsUtils.findObject(templateProcessor.getContext(), id);
             final String name = object.titleString();
-            String link = tagProcessor.getRequiredProperty(LINK_VIEW);
+            String link = templateProcessor.getRequiredProperty(LINK_VIEW);
             link += "?_result=" + id;
             crumbs.add(name, link);
         } else if (action.equals("return")) {
@@ -110,35 +111,35 @@ public class History extends AbstractElementProcessor {
 
     }
 
-    public void write(final Crumbs crumbs, final TagProcessor tagProcessor) {
+    public void write(final Crumbs crumbs, final TemplateProcessor templateProcessor) {
         if (crumbs.isEmpty()) {
             return;
         }
 
-        tagProcessor.appendHtml("<div id=\"history\">");
+        templateProcessor.appendHtml("<div id=\"history\">");
         int i = 0;
         final int length = crumbs.size();
         for (final Crumb crumb : crumbs.iterator()) {
             final String link = crumb.link;
             if (i > 0) {
-                tagProcessor.appendHtml("<span class=\"separator\"> | </span>");
+                templateProcessor.appendHtml("<span class=\"separator\"> | </span>");
             }
             if (i == length - 1 || link == null) {
-                tagProcessor.appendHtml("<span class=\"disabled\">");
-                tagProcessor.appendHtml(crumb.name);
-                tagProcessor.appendHtml("</span>");
+                templateProcessor.appendHtml("<span class=\"disabled\">");
+                templateProcessor.appendHtml(crumb.name);
+                templateProcessor.appendHtml("</span>");
             } else {
-                tagProcessor.appendHtml("<a class=\"linked\" href=\"" + link + "\">");
-                tagProcessor.appendHtml(crumb.name);
-                tagProcessor.appendHtml("</a>");
+                templateProcessor.appendHtml("<a class=\"linked\" href=\"" + link + "\">");
+                templateProcessor.appendHtml(crumb.name);
+                templateProcessor.appendHtml("</a>");
             }
             i++;
         }
-        tagProcessor.appendHtml("</div>");
+        templateProcessor.appendHtml("</div>");
     }
 
-    private Crumbs getCrumbs(final TagProcessor tagProcessor) {
-        final Request context = tagProcessor.getContext();
+    private Crumbs getCrumbs(final TemplateProcessor templateProcessor) {
+        final Request context = templateProcessor.getContext();
         Crumbs crumbs = (Crumbs) context.getVariable(_HISTORY);
         if (crumbs == null) {
             crumbs = new Crumbs();

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/other/VersionNumber.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/other/VersionNumber.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/other/VersionNumber.java
index 5ae6dff..5f8e8b0 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/other/VersionNumber.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/other/VersionNumber.java
@@ -24,7 +24,8 @@ import java.io.InputStreamReader;
 
 import org.apache.isis.viewer.scimpi.ScimpiException;
 import org.apache.isis.viewer.scimpi.dispatcher.context.Request;
-import org.apache.isis.viewer.scimpi.dispatcher.processor.TagProcessor;
+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 VersionNumber extends AbstractElementProcessor {
@@ -39,12 +40,12 @@ public class VersionNumber extends AbstractElementProcessor {
     }
 
     @Override
-    public void process(final TagProcessor tagProcessor) {
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
         if (version == null) {
             version = "0000"; // default revision number
-            loadRevisonNumber(tagProcessor.getContext());
+            loadRevisonNumber(templateProcessor.getContext());
         }
-        tagProcessor.appendHtml(version);
+        templateProcessor.appendHtml(version);
     }
 
     private void loadRevisonNumber(final Request context) {

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/security/EndSession.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/security/EndSession.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/security/EndSession.java
new file mode 100644
index 0000000..e14a0bb
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/security/EndSession.java
@@ -0,0 +1,37 @@
+/*
+ *  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.security;
+
+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 EndSession extends AbstractElementProcessor {
+
+    @Override
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
+        templateProcessor.getContext().endHttpSession();
+    }
+
+    @Override
+    public String getName() {
+        return "end-session";
+    }
+}

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/security/Logoff.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/security/Logoff.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/security/Logoff.java
new file mode 100644
index 0000000..c0452f9
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/security/Logoff.java
@@ -0,0 +1,39 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.viewer.scimpi.dispatcher.view.security;
+
+import org.apache.isis.viewer.scimpi.dispatcher.action.LogoutAction;
+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 Logoff extends AbstractElementProcessor {
+
+    @Override
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
+        LogoutAction.logoutUser(templateProcessor.getContext());
+    }
+
+    @Override
+    public String getName() {
+        return "logoff";
+    }
+
+}

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/security/Logon.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/security/Logon.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/security/Logon.java
new file mode 100644
index 0000000..f1325cf
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/security/Logon.java
@@ -0,0 +1,51 @@
+/*
+ *  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.security;
+
+
+import org.apache.isis.core.commons.authentication.AnonymousSession;
+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.RequestState;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.view.form.LogonFormAbstract;
+
+public class Logon extends LogonFormAbstract {
+
+    @Override
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
+        String view = templateProcessor.getOptionalProperty(VIEW);
+        Request context = templateProcessor.getContext();
+        if (view == null) {
+            view = (String) context.getVariable("login-path");
+        }
+
+        final boolean isNotLoggedIn = IsisContext.getSession().getAuthenticationSession() instanceof AnonymousSession;
+        if (isNotLoggedIn) {            
+            loginForm(templateProcessor, view);
+        }
+    }
+
+    @Override
+    public String getName() {
+        return "logon";
+    }
+
+}

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/security/RestrictAccess.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/security/RestrictAccess.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/security/RestrictAccess.java
new file mode 100644
index 0000000..de7b352
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/security/RestrictAccess.java
@@ -0,0 +1,42 @@
+/*
+ *  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.security;
+
+import org.apache.isis.viewer.scimpi.Names;
+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 RestrictAccess extends AbstractElementProcessor {
+    private static final String LOGIN_VIEW = "login-view";
+    private static final String DEFAULT_LOGIN_VIEW = "login." + Names.EXTENSION;
+
+    public String getName() {
+        return "restrict-access";
+    }
+
+    public void process(TemplateProcessor templateProcessor, RequestState state) {
+        if (!templateProcessor.getContext().isUserAuthenticated()) { 
+            final String view = templateProcessor.getOptionalProperty(LOGIN_VIEW, DEFAULT_LOGIN_VIEW);
+            templateProcessor.getContext().redirectTo(view);
+        }
+    }
+
+}
+

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/security/Secure.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/security/Secure.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/security/Secure.java
new file mode 100644
index 0000000..d312bf5
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/security/Secure.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.security;
+
+import org.apache.isis.core.commons.authentication.AnonymousSession;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+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 Secure extends AbstractElementProcessor {
+    private static final String LOGIN_VIEW = "login-view";
+
+    @Override
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
+        final boolean isLoggedIn = !(IsisContext.getSession().getAuthenticationSession() instanceof AnonymousSession);
+        if (!isLoggedIn) {
+            IsisContext.getMessageBroker().addWarning("You are not currently logged in! Please log in so you can continue.");
+            final String view = templateProcessor.getOptionalProperty(LOGIN_VIEW, "/login.shtml");
+            templateProcessor.getContext().redirectTo(view);
+        }
+    }
+
+    @Override
+    public String getName() {
+        return "secure";
+    }
+
+}

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/security/StartSession.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/security/StartSession.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/security/StartSession.java
new file mode 100644
index 0000000..dbc2b34
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/security/StartSession.java
@@ -0,0 +1,37 @@
+/*
+ *  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.security;
+
+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 StartSession extends AbstractElementProcessor {
+
+    @Override
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
+        templateProcessor.getContext().startHttpSession();
+    }
+
+    @Override
+    public String getName() {
+        return "start-session";
+    }
+}

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/security/User.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/security/User.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/security/User.java
new file mode 100644
index 0000000..3c7cb49
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/security/User.java
@@ -0,0 +1,78 @@
+/*
+ *  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.security;
+
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.scimpi.Names;
+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 User extends AbstractElementProcessor {
+    private static final String LOGIN_VIEW = "login-view";
+    private static final String DEFAULT_LOGIN_VIEW = "login." + Names.EXTENSION;
+    private static final String LOGOUT_VIEW = "logout-view";
+    private static final String DEFAULT_LOGOUT_VIEW = "logout." + Names.EXTENSION;
+
+    @Override
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
+        final boolean isAuthenticatedn = templateProcessor.getContext().isUserAuthenticated();
+        templateProcessor.appendHtml("<div class=\"user\">");
+        if (isAuthenticatedn) {
+            displayUserAndLogoutLink(templateProcessor);
+        } else {
+            displayLoginForm(templateProcessor);
+        }
+        templateProcessor.appendHtml("</div>");
+    }
+
+    public void displayLoginForm(final TemplateProcessor templateProcessor) {
+        String loginView = templateProcessor.getOptionalProperty(LOGIN_VIEW);
+        if (loginView == null) {
+            Logon.loginForm(templateProcessor, ".");
+        } else {
+            if (loginView.trim().length() == 0) {
+                loginView = DEFAULT_LOGIN_VIEW;
+            }
+            templateProcessor.appendHtml("<a div class=\"link\" href=\"" + loginView + "\">Log in</a>");
+        }
+    }
+
+    public void displayUserAndLogoutLink(final TemplateProcessor templateProcessor) {
+        String user = templateProcessor.getOptionalProperty(NAME);
+        if (user == null) {
+            user = (String) templateProcessor.getContext().getVariable("_username");
+        }
+        if (user == null) {
+            user = IsisContext.getAuthenticationSession().getUserName();
+        }
+        templateProcessor.appendHtml("Welcome <span class=\"name\">");
+        templateProcessor.appendAsHtmlEncoded(user);
+        templateProcessor.appendHtml("</span>, ");
+        final String logoutView = templateProcessor.getOptionalProperty(LOGOUT_VIEW, DEFAULT_LOGOUT_VIEW);
+        templateProcessor.appendHtml("<a class=\"link\" href=\"logout.app?view=" + logoutView + "\">Log out</a>");
+    }
+
+    @Override
+    public String getName() {
+        return "user";
+    }
+
+}