incubator-isis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From danhayw...@apache.org
Subject svn commit: r1295480 - in /incubator/isis/trunk/framework/viewer: html/ html/src/main/java/org/apache/isis/viewer/html/ html/src/main/java/org/apache/isis/viewer/html/action/ html/src/main/java/org/apache/isis/viewer/html/action/view/ html/src/main/jav...
Date Thu, 01 Mar 2012 09:07:58 GMT
Author: danhaywood
Date: Thu Mar  1 09:07:57 2012
New Revision: 1295480

URL: http://svn.apache.org/viewvc?rev=1295480&view=rev
Log:
ISIS-209: improving back-button handling in html viewer - don't clear out actionMap on every request (plus refactoring/reformatting tidy up)

Added:
    incubator/isis/trunk/framework/viewer/html/src/test/java/org/apache/isis/viewer/html/context/ContextTest_serialization.java   (with props)
Removed:
    incubator/isis/trunk/framework/viewer/html/src/test/java/org/apache/isis/viewer/html/component/
Modified:
    incubator/isis/trunk/framework/viewer/html/pom.xml
    incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/PathBuilder.java
    incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/PathBuilderDefault.java
    incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/action/LogOut.java
    incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/action/view/ObjectViewAbstract.java
    incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/component/html/HtmlComponentFactory.java
    incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/CollectionMapping.java
    incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/Context.java
    incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/ObjectHistory.java
    incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/ObjectMapping.java
    incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/PersistentObjectMapping.java
    incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/TransientObjectMapping.java
    incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/servlet/AbstractHtmlViewerServlet.java
    incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/servlet/ControllerServlet.java
    incubator/isis/trunk/framework/viewer/wicket/wicket-viewer/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication_init.java

Modified: incubator/isis/trunk/framework/viewer/html/pom.xml
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/html/pom.xml?rev=1295480&r1=1295479&r2=1295480&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/html/pom.xml (original)
+++ incubator/isis/trunk/framework/viewer/html/pom.xml Thu Mar  1 09:07:57 2012
@@ -102,6 +102,12 @@
 
         <dependency>
             <groupId>org.apache.isis.core</groupId>
+            <artifactId>testsupport</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.isis.core</groupId>
             <artifactId>progmodel</artifactId>
         </dependency>
 		<dependency>

Modified: incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/PathBuilder.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/PathBuilder.java?rev=1295480&r1=1295479&r2=1295480&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/PathBuilder.java (original)
+++ incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/PathBuilder.java Thu Mar  1 09:07:57 2012
@@ -19,7 +19,9 @@
 
 package org.apache.isis.viewer.html;
 
-public interface PathBuilder {
+import java.io.Serializable;
+
+public interface PathBuilder extends Serializable {
 
     public String getSuffix();
 

Modified: incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/PathBuilderDefault.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/PathBuilderDefault.java?rev=1295480&r1=1295479&r2=1295480&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/PathBuilderDefault.java (original)
+++ incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/PathBuilderDefault.java Thu Mar  1 09:07:57 2012
@@ -25,21 +25,23 @@ import org.apache.isis.viewer.html.servl
 
 public class PathBuilderDefault implements PathBuilder {
 
+    private static final long serialVersionUID = 1L;
+    
     private final String suffix;
 
+    private static String getSuffixInitParam(final ServletContext servletContext) {
+        final String suffixInitParam = servletContext.getInitParameter(HtmlServletConstants.SUFFIX_INIT_PARAM);
+        return suffixInitParam != null ? suffixInitParam : HtmlServletConstants.SUFFIX_INIT_PARAM_VALUE_DEFAULT;
+    }
+
     public PathBuilderDefault(final ServletContext servletContext) {
         this(getSuffixInitParam(servletContext));
     }
 
-    private PathBuilderDefault(final String suffix) {
+    public PathBuilderDefault(final String suffix) {
         this.suffix = suffix;
     }
 
-    private static String getSuffixInitParam(final ServletContext servletContext) {
-        final String suffixInitParam = servletContext.getInitParameter(HtmlServletConstants.SUFFIX_INIT_PARAM);
-        return suffixInitParam != null ? suffixInitParam : HtmlServletConstants.SUFFIX_INIT_PARAM_VALUE_DEFAULT;
-    }
-
     @Override
     public String getSuffix() {
         return suffix;

Modified: incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/action/LogOut.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/action/LogOut.java?rev=1295480&r1=1295479&r2=1295480&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/action/LogOut.java (original)
+++ incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/action/LogOut.java Thu Mar  1 09:07:57 2012
@@ -33,12 +33,6 @@ public class LogOut implements Action {
         if (authSession != null) {
             getAuthenticationManager().closeSession(authSession);
         }
-        context.setSession(null); // setSession is probably redundant since now
-                                  // always available via IsisContext
-                                  // can't rely on it being set because Filter
-                                  // may set httpSession
-                                  // (if in exploration mode) rather than ever
-                                  // hitting the LogonServlet
         context.invalidate();
     }
 

Modified: incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/action/view/ObjectViewAbstract.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/action/view/ObjectViewAbstract.java?rev=1295480&r1=1295479&r2=1295480&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/action/view/ObjectViewAbstract.java (original)
+++ incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/action/view/ObjectViewAbstract.java Thu Mar  1 09:07:57 2012
@@ -54,7 +54,7 @@ public abstract class ObjectViewAbstract
             context.addObjectToHistory(idString);
         }
 
-        context.purge();
+        context.purgeObjectsAndCollections();
 
         content.setMenu(MenuUtil.menu(adapter, idString, context));
 

Modified: incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/component/html/HtmlComponentFactory.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/component/html/HtmlComponentFactory.java?rev=1295480&r1=1295479&r2=1295480&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/component/html/HtmlComponentFactory.java (original)
+++ incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/component/html/HtmlComponentFactory.java Thu Mar  1 09:07:57 2012
@@ -49,41 +49,87 @@ import org.apache.isis.viewer.html.compo
 
 public class HtmlComponentFactory implements ComponentFactory {
 
+    private static final long serialVersionUID = 1L;
+    
     protected final String footer;
     protected final String header;
     protected final String styleSheet;
+    
     private final PathBuilder pathBuilder;
 
     public HtmlComponentFactory(final PathBuilder pathBuilder) {
+        this(pathBuilder, getConfiguration());
+    }
+
+    public HtmlComponentFactory(final PathBuilder pathBuilder, final IsisConfiguration configuration) {
         this.pathBuilder = pathBuilder;
-        final IsisConfiguration configuration = getConfiguration();
-        styleSheet = configuration.getString(STYLE_SHEET);
-        String file = configuration.getString(HEADER_FILE);
-        header = file == null ? configuration.getString(HEADER) : loadFile(file);
-        file = configuration.getString(FOOTER_FILE);
-        footer = file == null ? configuration.getString(FOOTER) : loadFile(file);
+        this.styleSheet = configuration.getString(STYLE_SHEET);
+        this.header = loadFileElseDefault(configuration, HEADER_FILE, HEADER);
+        this.footer = loadFileElseDefault(configuration, FOOTER_FILE, FOOTER);
     }
 
+    
+    // /////////////////////////////////////////////////////////////
+    // Pages
+    // /////////////////////////////////////////////////////////////
+
     @Override
-    public Block createBlock(final String style, final String description) {
-        return new Div(this, style, description);
+    public Page createPage() {
+        return new DynamicHtmlPage(this, styleSheet, header, footer);
+    }
+
+    public LogonFormPage createLogonPage(final String user, final String password, final boolean registerLink, final String error) {
+        return new LogonFormPage(this, styleSheet, header, footer, user, password, registerLink, error);
+    }
+
+    public RegisterFormPage createRegisterPage(final String user, final String password, final String error) {
+        return new RegisterFormPage(this, styleSheet, header, footer, user, password, error);
     }
 
+    // /////////////////////////////////////////////////////////////
+    // Menus
+    // /////////////////////////////////////////////////////////////
+
     @Override
-    public Component createBreadCrumbs(final String[] names, final boolean[] isLinked) {
-        return new BreadCrumbs(this, names, isLinked);
+    public Component createMenuItem(final String actionId, final String name, final String description, final String reasonDisabled, final ActionType type, final boolean hasParameters, final String targetObjectId) {
+        return new MenuItem(this, actionId, name, description, reasonDisabled, type, hasParameters, targetObjectId);
     }
 
     @Override
+    public Component createSubmenu(final String menuName, final Component[] items) {
+        return new Submenu(menuName, items);
+    }
+
+
+    // /////////////////////////////////////////////////////////////
+    // Icons
+    // /////////////////////////////////////////////////////////////
+
+    @Override
     public Component createCollectionIcon(final ObjectAssociation field, final ObjectAdapter collection, final String id) {
         return new CollectionLink(this, field, collection, field.getDescription(), id);
     }
 
     @Override
-    public DebugPane createDebugPane() {
-        return new HtmlDebug();
+    public Component createCollectionIcon(final ObjectAdapter collection, final String collectionId) {
+        return new CollectionIcon(this, collection, collection.getSpecification().getDescription(), collectionId);
+    }
+
+    @Override
+    public Component createObjectIcon(final ObjectAdapter object, final String objectId, final String style) {
+        return new ObjectIcon(this, object, object.getSpecification().getDescription(), objectId, style);
+    }
+
+    @Override
+    public Component createObjectIcon(final ObjectAssociation field, final ObjectAdapter object, final String objectId, final String style) {
+        return new ObjectIcon(this, object, field.getDescription(), objectId, style);
     }
 
+
+    // /////////////////////////////////////////////////////////////
+    // Options
+    // /////////////////////////////////////////////////////////////
+
     @Override
     public Component createEditOption(final String id) {
         return new ActionComponent(this, "edit", "Edit Object", "Edit the current object", id, null, null);
@@ -99,24 +145,24 @@ public class HtmlComponentFactory implem
         return new ActionComponent(this, "add", "Add Item", "Add item to collection", id, null, fieldName);
     }
 
+
+    // /////////////////////////////////////////////////////////////
+    // Messages
+    // /////////////////////////////////////////////////////////////
+
     @Override
     public Component createErrorMessage(final Exception e, final boolean isDebug) {
         return new ErrorMessage(e, isDebug);
     }
 
-    @Override
-    public Form createForm(final String id, final String actionName, final int step, final int noOfPages, final boolean isEditing) {
-        return new HtmlForm(this, id, actionName, step, noOfPages, isEditing);
-    }
 
-    @Override
-    public Component createHeading(final String name) {
-        return new Heading(this, name, 4);
-    }
+    // /////////////////////////////////////////////////////////////
+    // Form & Form Widgets
+    // /////////////////////////////////////////////////////////////
 
     @Override
-    public Component createInlineBlock(final String style, final String text, final String description) {
-        return new Span(style, text, description);
+    public Form createForm(final String id, final String actionName, final int step, final int noOfPages, final boolean isEditing) {
+        return new HtmlForm(this, id, actionName, step, noOfPages, isEditing);
     }
 
     @Override
@@ -125,46 +171,58 @@ public class HtmlComponentFactory implem
     }
 
     @Override
-    public Component createSubmenu(final String menuName, final Component[] items) {
-        return new Submenu(menuName, items);
-    }
-
-    @Override
     public Component createLink(final String link, final String name, final String description) {
         return new Link(this, link, name, description);
     }
 
-    @Override
-    public Component createMenuItem(final String actionId, final String name, final String description, final String reasonDisabled, final ActionType type, final boolean hasParameters, final String targetObjectId) {
-        return new MenuItem(this, actionId, name, description, reasonDisabled, type, hasParameters, targetObjectId);
-    }
 
     @Override
-    public Component createCollectionIcon(final ObjectAdapter collection, final String collectionId) {
-        return new CollectionIcon(this, collection, collection.getSpecification().getDescription(), collectionId);
+    public Component createParseableField(final ObjectAssociation field, final ObjectAdapter value, final boolean isEditable) {
+        final BooleanValueFacet facet = field.getSpecification().getFacet(BooleanValueFacet.class);
+        if (facet != null) {
+            return createCheckboxBlock(isEditable, facet.isSet(value));
+        } else {
+            final String titleString = value != null ? value.titleString() : "";
+
+            final MultiLineFacet multiLineFacet = field.getSpecification().getFacet(MultiLineFacet.class);
+            final boolean isWrapped = multiLineFacet != null && !multiLineFacet.preventWrapping();
+
+            if (isWrapped) {
+                return createInlineBlock("value", "<pre>" + titleString + "</pre>", null);
+            } else {
+                return createInlineBlock("value", titleString, null);
+            }
+        }
     }
 
     @Override
-    public Component createObjectIcon(final ObjectAdapter object, final String objectId, final String style) {
-        return new ObjectIcon(this, object, object.getSpecification().getDescription(), objectId, style);
+    public Table createTable(final int noColumns, final boolean withSelectorColumn) {
+        return new HtmlTable(this, noColumns, withSelectorColumn);
     }
 
+
+    // /////////////////////////////////////////////////////////////
+    // Furniture
+    // /////////////////////////////////////////////////////////////
+
     @Override
-    public Component createObjectIcon(final ObjectAssociation field, final ObjectAdapter object, final String objectId, final String style) {
-        return new ObjectIcon(this, object, field.getDescription(), objectId, style);
+    public Block createBlock(final String style, final String description) {
+        return new Div(this, style, description);
     }
 
     @Override
-    public Page createPage() {
-        return new DynamicHtmlPage(this, styleSheet, header, footer);
+    public Component createBreadCrumbs(final String[] names, final boolean[] isLinked) {
+        return new BreadCrumbs(this, names, isLinked);
     }
 
-    public LogonFormPage createLogonPage(final String user, final String password, final boolean registerLink, final String error) {
-        return new LogonFormPage(this, styleSheet, header, footer, user, password, registerLink, error);
+    @Override
+    public Component createInlineBlock(final String style, final String text, final String description) {
+        return new Span(style, text, description);
     }
 
-    public RegisterFormPage createRegisterPage(final String user, final String password, final String error) {
-        return new RegisterFormPage(this, styleSheet, header, footer, user, password, error);
+    @Override
+    public Component createHeading(final String name) {
+        return new Heading(this, name, 4);
     }
 
     @Override
@@ -173,36 +231,47 @@ public class HtmlComponentFactory implem
     }
 
     @Override
-    public Table createTable(final int noColumns, final boolean withSelectorColumn) {
-        return new HtmlTable(this, noColumns, withSelectorColumn);
+    public Component createUserSwap(final String name) {
+        return new UserSwapLink(this, name);
+
     }
 
+    // /////////////////////////////////////////////////////////////
+    // Debug
+    // /////////////////////////////////////////////////////////////
+
     @Override
-    public Component createUserSwap(final String name) {
-        return new UserSwapLink(this, name);
+    public DebugPane createDebugPane() {
+        return new HtmlDebug();
+    }
 
+
+    // /////////////////////////////////////////////////////////////
+    // PathBuilder impl
+    // /////////////////////////////////////////////////////////////
+
+    @Override
+    public String getSuffix() {
+        return pathBuilder.getSuffix();
     }
 
     @Override
-    public Component createParseableField(final ObjectAssociation field, final ObjectAdapter value, final boolean isEditable) {
-        final BooleanValueFacet facet = field.getSpecification().getFacet(BooleanValueFacet.class);
-        if (facet != null) {
-            return createCheckboxBlock(isEditable, facet.isSet(value));
-        } else {
-            final String titleString = value != null ? value.titleString() : "";
+    public String pathTo(final String prefix) {
+        return pathBuilder.pathTo(prefix);
+    }
 
-            final MultiLineFacet multiLineFacet = field.getSpecification().getFacet(MultiLineFacet.class);
-            final boolean isWrapped = multiLineFacet != null && !multiLineFacet.preventWrapping();
+    
+    // /////////////////////////////////////////////////////////////
+    // helpers
+    // /////////////////////////////////////////////////////////////
 
-            if (isWrapped) {
-                return createInlineBlock("value", "<pre>" + titleString + "</pre>", null);
-            } else {
-                return createInlineBlock("value", titleString, null);
-            }
-        }
+    private static String loadFileElseDefault(final IsisConfiguration configuration, final String fileConstant, final String literalConstant) {
+        final String fileName = configuration.getString(fileConstant);
+        return fileName != null ? loadFile(fileName) : configuration.getString(literalConstant);
     }
 
-    private String loadFile(final String file) {
+
+    private static String loadFile(final String file) {
         final StringBuffer content = new StringBuffer();
         BufferedReader reader = null;
         try {
@@ -227,21 +296,13 @@ public class HtmlComponentFactory implem
         return content.toString();
     }
 
-    @Override
-    public String getSuffix() {
-        return pathBuilder.getSuffix();
-    }
-
-    @Override
-    public String pathTo(final String prefix) {
-        return pathBuilder.pathTo(prefix);
-    }
+    
 
     // /////////////////////////////////////////////////////////////
     // injected services
     // /////////////////////////////////////////////////////////////
 
-    protected IsisConfiguration getConfiguration() {
+    private static IsisConfiguration getConfiguration() {
         return IsisContext.getConfiguration();
     }
 

Modified: incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/CollectionMapping.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/CollectionMapping.java?rev=1295480&r1=1295479&r2=1295480&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/CollectionMapping.java (original)
+++ incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/CollectionMapping.java Thu Mar  1 09:07:57 2012
@@ -19,8 +19,10 @@
 
 package org.apache.isis.viewer.html.context;
 
-import java.util.Enumeration;
-import java.util.Vector;
+import java.util.Iterator;
+import java.util.List;
+
+import com.google.common.collect.Lists;
 
 import org.apache.isis.core.commons.debug.DebugBuilder;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
@@ -36,8 +38,9 @@ import org.apache.isis.runtimes.dflt.run
  * Has value semantics based on the value semantics of the underlying list that
  * it wraps.
  */
-public class CollectionMapping {
-    private final Vector list = new Vector();
+public class CollectionMapping implements Iterable<String> {
+    
+    private final List<String> list = Lists.newArrayList();
     private final ObjectSpecification elementSpecification;
 
     public CollectionMapping(final Context context, final ObjectAdapter collection) {
@@ -45,38 +48,70 @@ public class CollectionMapping {
         elementSpecification = typeOfFacet.valueSpec();
 
         final CollectionFacet collectionFacet = CollectionFacetUtils.getCollectionFacetFromSpec(collection);
-        final Enumeration elements = collectionFacet.elements(collection);
-        while (elements.hasMoreElements()) {
-            final ObjectAdapter element = (ObjectAdapter) elements.nextElement();
-            list.add(context.mapObject(element));
+        
+        for (ObjectAdapter element : collectionFacet.iterable(collection)) {
+            final String objectId = context.mapObject(element);
+            list.add(objectId);
         }
     }
 
     public ObjectAdapter getCollection(final Context context) {
-        final Vector elements = new Vector();
-        final Enumeration e = list.elements();
-        while (e.hasMoreElements()) {
-            final String elementId = (String) e.nextElement();
+        final List<Object> elementPojos = Lists.newArrayList();
+        
+        for (String elementId : list) {
             final ObjectAdapter adapter = context.getMappedObject(elementId);
-            elements.add(adapter.getObject());
+            final Object pojo = adapter.getObject();
+            elementPojos.add(pojo);
         }
-        return getAdapterManager().adapterFor(elements);
+        return getAdapterManager().adapterFor(elementPojos);
     }
 
     public ObjectSpecification getElementSpecification() {
         return elementSpecification;
     }
 
+    
+    public Iterator<String> iterator() {
+        return list.iterator();
+    }
+
+    public boolean contains(final String id) {
+        for (String elementId : list) {
+            if (elementId.equals(id)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public void remove(final String existingId) {
+        for (final String elementId: list) {
+            if (elementId.equals(existingId)) {
+                list.remove(existingId);
+                break;
+            }
+        }
+    }
+
+
+    // //////////////////////////////////////////////////////
+    // debugging
+    // //////////////////////////////////////////////////////
+
     public void debug(final DebugBuilder debug) {
         debug.indent();
-        final Enumeration e = list.elements();
-        while (e.hasMoreElements()) {
-            final String elementId = (String) e.nextElement();
+        for (String elementId : list) {
             debug.appendln(elementId);
         }
         debug.unindent();
     }
 
+
+
+    // //////////////////////////////////////////////////////
+    // equals, hashCode
+    // //////////////////////////////////////////////////////
+
     /**
      * Value semantics based on the identity of the underlying list that this
      * wraps.
@@ -104,30 +139,6 @@ public class CollectionMapping {
         return this.list.equals(other.list);
     }
 
-    public boolean contains(final String id) {
-        final Enumeration e = list.elements();
-        while (e.hasMoreElements()) {
-            final String elementId = (String) e.nextElement();
-            if (elementId.equals(id)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public Enumeration elements() {
-        return list.elements();
-    }
-
-    public void remove(final String existingId) {
-        for (final Object entry : list) {
-            if (entry.equals(existingId)) {
-                list.remove(existingId);
-                break;
-            }
-        }
-    }
-
     // //////////////////////////////////////////////////////
     // Dependencies (from context)
     // //////////////////////////////////////////////////////

Modified: incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/Context.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/Context.java?rev=1295480&r1=1295479&r2=1295480&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/Context.java (original)
+++ incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/Context.java Thu Mar  1 09:07:57 2012
@@ -20,15 +20,14 @@
 package org.apache.isis.viewer.html.context;
 
 import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
 import java.util.Stack;
 
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
 import org.apache.log4j.Logger;
 
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
@@ -42,6 +41,8 @@ import org.apache.isis.core.runtime.user
 import org.apache.isis.runtimes.dflt.runtime.persistence.ConcurrencyException;
 import org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext;
 import org.apache.isis.runtimes.dflt.runtime.system.persistence.AdapterManager;
+import org.apache.isis.runtimes.dflt.runtime.system.persistence.PersistenceSession;
+import org.apache.isis.runtimes.dflt.runtime.system.transaction.UpdateNotifier;
 import org.apache.isis.viewer.html.component.Block;
 import org.apache.isis.viewer.html.component.ComponentFactory;
 import org.apache.isis.viewer.html.crumb.CollectionCrumb;
@@ -53,36 +54,138 @@ import org.apache.isis.viewer.html.reque
 import org.apache.isis.viewer.html.task.Task;
 
 public class Context {
+
     private static final Logger LOG = Logger.getLogger(Context.class);
-    private final Map actionMap = new HashMap();
+    
     private final ComponentFactory componentFactory;
     private final ObjectHistory history = new ObjectHistory();
-    private boolean isValid;
-    private int max;
-    private final Map<String, CollectionMapping> collectionMap = new HashMap<String, CollectionMapping>();
-    private final Map<String, ObjectMapping> objectMap = new HashMap<String, ObjectMapping>();
-    private final Map<String, ObjectMapping> serviceMap = new HashMap<String, ObjectMapping>();
+    
+    private final Map<String, ObjectMapping> objectMap = Maps.newHashMap();
+    private final Map<String, ObjectMapping> serviceMap = Maps.newHashMap();
+    private final Map<String, CollectionMapping> collectionMap = Maps.newHashMap();
+    private final Map<String, ObjectAction> actionMap = Maps.newHashMap();
+    
     private final Stack<Crumb> crumbs = new Stack<Crumb>();
     private final List<String> messages = new ArrayList<String>();
     private final List<String> warnings = new ArrayList<String>();
 
     private AuthenticationSession session;
+    private boolean isValid;
+    private int max;
 
-    public Context(final ComponentFactory factory) {
-        componentFactory = factory;
-        isValid = true;
+    // ////////////////////////////////////////////////////
+    // constructor, init
+    // ////////////////////////////////////////////////////
+
+    public Context(final ComponentFactory componentFactory) {
+        this.componentFactory = componentFactory;
+        this.isValid = true;
         clearMessagesAndWarnings();
-        LOG.debug(this + " created with " + factory);
+        LOG.debug(this + " created with " + componentFactory);
     }
 
-    public void setObjectCrumb(final ObjectAdapter object) {
-        while (crumbs.size() > 0 && !(crumbs.lastElement() instanceof TaskCrumb)) {
+    public void init() {
+        final AdapterManager adapterManager = getAdapterManager();
+        final List<Object> services = getUserProfile().getPerspective().getServices();
+        for (final Object service : services) {
+            final ObjectAdapter serviceAdapter = adapterManager.adapterFor(service);
+            if (serviceAdapter == null) {
+                LOG.warn("unable to find service: " + service + "; skipping");
+                continue;
+            }
+            mapObject(serviceAdapter);
+        }
+        serviceMap.putAll(objectMap);
+    }
+
+
+    public ComponentFactory getComponentFactory() {
+        return componentFactory;
+    }
+
+
+    // ////////////////////////////////////////////////////
+    // validity 
+    // ////////////////////////////////////////////////////
+
+    public boolean isValid() {
+        return isValid;
+    }
+
+    public void invalidate() {
+        isValid = false;
+    }
+    
+    
+    // ////////////////////////////////////////////////////
+    // session 
+    // ////////////////////////////////////////////////////
+
+    public boolean isLoggedIn() {
+        return session != null;
+    }
+
+    public void setSession(final AuthenticationSession currentSession) {
+        this.session = currentSession;
+    }
+
+    public AuthenticationSession getSession() {
+        return session;
+    }
+
+
+    // ////////////////////////////////////////////////////
+    // processChanges 
+    // ////////////////////////////////////////////////////
+
+    public void processChanges() {
+        final List<ObjectAdapter> disposedObjects = getUpdateNotifier().getDisposedObjects();
+        for (final ObjectAdapter adapter : disposedObjects) {
+            final ObjectMapping mapping = persistentOrTransientObjectMappingFor(adapter);
+            if (objectMap.containsValue(mapping)) {
+                processChangeFor(mapping);
+            }
+        }
+    }
+
+    private void processChangeFor(final ObjectMapping mapping) {
+        final String existingId = findExistingInMap(objectMap, mapping);
+        history.remove(existingId);
+
+        final List<Crumb> relatedCrumbs = Lists.newArrayList();
+        for (final Crumb crumb : getCrumbs()) {
+            /*
+             * if (crumb.isFor(existingId)) { relatedCrumbs.add(crumb);
+             * }
+             */}
+        for (final Crumb crumb : relatedCrumbs) {
+            crumbs.remove(crumb);
+        }
+
+        for (final CollectionMapping collection : collectionMap.values()) {
+            collection.remove(existingId);
+        }
+        objectMap.remove(existingId);
+    }
+
+    // ////////////////////////////////////////////////////
+    // changeContext 
+    // ////////////////////////////////////////////////////
+
+    public Request changeContext(final int id) {
+        while (crumbs.size() - 1 > id) {
             crumbs.pop();
         }
-        final String id = mapObject(object);
-        crumbs.push(new ObjectCrumb(id, object));
+        final Crumb c = crumbs.lastElement();
+        return c.changeContext();
     }
 
+
+    
+    // ////////////////////////////////////////////////////
+    // Crumbs
+    // ////////////////////////////////////////////////////
+
     public void addCollectionFieldCrumb(final String collectionFieldName) {
         crumbs.push(new ObjectFieldCrumb(collectionFieldName));
     }
@@ -94,6 +197,15 @@ public class Context {
         crumbs.push(new CollectionCrumb(id, getMappedCollection(id)));
     }
 
+    public void setObjectCrumb(final ObjectAdapter object) {
+        while (crumbs.size() > 0 && !(crumbs.lastElement() instanceof TaskCrumb)) {
+            crumbs.pop();
+        }
+        final String id = mapObject(object);
+        crumbs.push(new ObjectCrumb(id, object));
+    }
+
+
     public void addTaskCrumb(final Task task) {
         while (crumbs.size() > 1 && !(crumbs.lastElement() instanceof ObjectCrumb)) {
             crumbs.pop();
@@ -104,107 +216,88 @@ public class Context {
         crumbs.push(new TaskCrumb(task));
     }
 
-    public void debug(final DebugBuilder debug) {
-        debug.startSection("Web Session Context");
-        debug.appendAsHexln("hash", hashCode());
-        debug.appendln("session", session);
-        debug.appendln("is valid", isValid);
-        debug.appendln("next id", max);
-        debug.appendln("factory", componentFactory);
-        debug.appendln("is task", isTask());
-
-        debug.appendln("crumbs (" + crumbs.size() + ")");
-
-        debug.indent();
+    
+    public Crumb[] getCrumbs() {
+        final int size = crumbs.size();
+        final Crumb[] taskList = new Crumb[size];
         for (int i = 0; i < crumbs.size(); i++) {
-            final Crumb crumb = crumbs.get(i);
-            debug.appendln(i + 1 + ". " + crumb);
-            debug.indent();
-            crumb.debug(debug);
-            debug.unindent();
+            taskList[i] = crumbs.get(i);
         }
-        debug.unindent();
+        return taskList;
+    }
 
-        debug.startSection("Objects");
-        for (final String id : objectMap.keySet()) {
-            final ObjectMapping object = objectMap.get(id);
-            debug.appendln(id + " -> " + object.getOid());
-            debug.indent();
-            object.debug(debug);
-            debug.unindent();
+    public boolean[] isLinked() {
+        final int size = crumbs.size();
+        final boolean[] isLinked = new boolean[size];
+        for (int i = size - 1; i >= 0; i--) {
+            final boolean isTask = crumbs.elementAt(i) instanceof TaskCrumb;
+            isLinked[i] = i != size - 1;
+            if (isTask) {
+                break;
+            }
         }
-        debug.endSection();
+        return isLinked;
+    }
 
-        debug.startSection("Collections");
-        for (final String id : collectionMap.keySet()) {
-            final CollectionMapping coll = collectionMap.get(id);
-            debug.appendln(id + " -> collection of " + coll.getElementSpecification().getPluralName());
-            coll.debug(debug);
-        }
-        debug.endSection();
 
-        debug.startSection("Actions");
-        debugMap(debug, actionMap);
-        debug.endSection();
+    // ////////////////////////////////////////////////////
+    // Mappings
+    // ////////////////////////////////////////////////////
 
-        debug.startSection("History");
-        history.debug(debug);
-        debug.endSection();
+    public String mapAction(final ObjectAction action) {
+        return findExistingOrAddToMap(actionMap, action);
+    }
 
-        debug.endSection();
+    public String mapObject(final ObjectAdapter adapter) {
+        return findExistingOrAddToMap(objectMap, persistentOrTransientObjectMappingFor(adapter));
     }
 
-    private void debugMap(final DebugBuilder debug, final Map map) {
-        final Iterator names = map.keySet().iterator();
-        while (names.hasNext()) {
-            final String name = (String) names.next();
-            debug.appendln(name + " -> " + map.get(name));
-        }
+    public String mapCollection(final ObjectAdapter collection) {
+        return findExistingOrAddToMap(collectionMap, new CollectionMapping(this, collection));
     }
 
     public ObjectAction getMappedAction(final String id) {
-        return (ObjectAction) getMappedInstance(actionMap, id);
+        return getMappedInstance(actionMap, id);
     }
 
-    public ComponentFactory getComponentFactory() {
-        return componentFactory;
+    public ObjectAdapter getMappedCollection(final String id) {
+        final CollectionMapping map = getMappedInstance(collectionMap, id);
+        return map.getCollection(this);
     }
 
-    /**
-     * Returns an array of instances of the specified type that are currently
-     * known in the current context, ie have been recently seen by the user.
-     * 
-     * <p>
-     * These will be resolved if required, with a transaction created (and
-     * ended) if required.
-     */
-    public ObjectAdapter[] getKnownInstances(final ObjectSpecification type) {
-
-        final List<ObjectAdapter> instances = new ArrayList<ObjectAdapter>();
+    public ObjectAdapter getMappedObject(final String id) {
+        final ObjectMapping mappedObject = getMappedInstance(objectMap, id);
+        final ObjectAdapter object = mappedObject.getObject();
 
-        for (final String id : objectMap.keySet()) {
-            final ObjectAdapter adapter = getMappedObject(id);
-            IsisContext.getPersistenceSession().resolveImmediately(adapter);
-            if (adapter.getSpecification().isOfType(type)) {
-                instances.add(adapter);
-            }
+        // ensure resolved if currently a ghost;
+        // start/end xactn if required
+        if (object.isPersistent() && object.getResolveState().isGhost()) {
+            getPersistenceSession().resolveImmediately(object);
         }
 
-        final ObjectAdapter[] array = new ObjectAdapter[instances.size()];
-        instances.toArray(array);
-        return array;
+        try {
+            mappedObject.checkVersion(object);
+        } catch (final ConcurrencyException e) {
+            LOG.info("concurrency conflict: " + e.getMessage());
+            messages.clear();
+            messages.add(e.getMessage());
+            messages.add("Reloaded object " + object.titleString());
+            updateVersion(object);
+        }
+        return object;
     }
 
-    private String addToMap(final Map map, final Object object) {
+    
+    private <T> String findExistingOrAddToMap(final Map<String,T> map, final T object) {
         Assert.assertNotNull(object);
         if (map.containsValue(object)) {
-            return findExistingId(map, object);
+            return findExistingInMap(map, object);
         } else {
-            return mapNewObject(map, object);
+            return addToMap(map, object);
         }
     }
 
-    private String mapNewObject(final Map map, final Object object) {
+    private <T> String addToMap(final Map<String,T> map, final T object) {
         max++;
         final String id = "" + max;
         map.put(id, object);
@@ -215,7 +308,7 @@ public class Context {
         return id;
     }
 
-    private String findExistingId(final Map<String, ?> map, final Object object) {
+    private <T> String findExistingInMap(final Map<String, T> map, final Object object) {
         for (final String id : map.keySet()) {
             if (object.equals(map.get(id))) {
                 return id;
@@ -224,42 +317,114 @@ public class Context {
         throw new IsisException();
     }
 
-    private Object getMappedInstance(final Map map, final String id) {
-        final Object object = map.get(id);
+    private <T> T getMappedInstance(final Map<String,T> map, final String id) {
+        final T object = map.get(id);
         if (object == null) {
-            final String mapName = (map == objectMap) ? "object" : (map == collectionMap ? "collection" : "action");
+            final String mapName = mapNameFor(map);
             throw new ObjectLookupException("No object in " + mapName + " map with id " + id);
         }
         return object;
     }
 
-    public ObjectAdapter getMappedCollection(final String id) {
-        final CollectionMapping map = (CollectionMapping) getMappedInstance(collectionMap, id);
-        return map.getCollection(this);
+    private <T> String mapNameFor(final Map<String, T> map) {
+        return (map == objectMap) ? "object" : (map == collectionMap ? "collection" : "action");
     }
 
-    public ObjectAdapter getMappedObject(final String id) {
-        final ObjectMapping mappedObject = (ObjectMapping) getMappedInstance(objectMap, id);
-        final ObjectAdapter object = mappedObject.getObject();
+    private static ObjectMapping persistentOrTransientObjectMappingFor(final ObjectAdapter adapter) {
+        return adapter.isTransient() ? new TransientObjectMapping(adapter) : new PersistentObjectMapping(adapter);
+    }
 
-        // ensure resolved if currently a ghost;
-        // start/end xactn if required
-        if (object.isPersistent() && object.getResolveState().isGhost()) {
-            IsisContext.getPersistenceSession().resolveImmediately(object);
+    
+
+    // ////////////////////////////////////////////////////
+    // Instances 
+    // ////////////////////////////////////////////////////
+
+    /**
+     * Returns an array of instances of the specified type that are currently
+     * known in the current context, ie have been recently seen by the user.
+     * 
+     * <p>
+     * These will be resolved if required, with a transaction created (and
+     * ended) if required.
+     */
+    public ObjectAdapter[] getKnownInstances(final ObjectSpecification type) {
+
+        final List<ObjectAdapter> instances = Lists.newArrayList();
+
+        for (final String id : objectMap.keySet()) {
+            final ObjectAdapter adapter = getMappedObject(id);
+            
+            getPersistenceSession().resolveImmediately(adapter);
+            if (adapter.getSpecification().isOfType(type)) {
+                instances.add(adapter);
+            }
         }
 
-        try {
-            mappedObject.checkVersion(object);
-        } catch (final ConcurrencyException e) {
-            LOG.info("concurrency conflict: " + e.getMessage());
-            messages.clear();
-            messages.add(e.getMessage());
-            messages.add("Reloaded object " + object.titleString());
-            updateVersion(object);
+        final ObjectAdapter[] array = new ObjectAdapter[instances.size()];
+        instances.toArray(array);
+        return array;
+    }
+
+    public void restoreAllObjectsToLoader() {
+        for (Map.Entry<String, ObjectMapping> mapEntry : objectMap.entrySet()) {
+            final ObjectMapping objectMapping = mapEntry.getValue();
+            objectMapping.restoreToLoader();
         }
-        return object;
     }
 
+    public void purgeObjectsAndCollections() {
+        
+        clearMessagesAndWarnings();
+
+        final Map<String, CollectionMapping> collMappingById = Maps.newHashMap();
+        final Map<String, ObjectMapping> objectMappingById = Maps.newHashMap();
+
+        for (HistoryEntry entry : history) {
+            if (entry.type == HistoryEntry.OBJECT) {
+                copyObjectMapping(objectMappingById, entry);
+            } else if (entry.type == HistoryEntry.COLLECTION) {
+                copyCollectionMapping(collMappingById, objectMappingById, entry);
+            }
+        }
+
+        collectionMap.clear();
+        collectionMap.putAll(collMappingById);
+        objectMap.clear();
+        objectMap.putAll(objectMappingById);
+        objectMap.putAll(serviceMap);
+    }
+
+    private void copyObjectMapping(final Map<String, ObjectMapping> objectMappingById, HistoryEntry entry) {
+        final ObjectMapping item = objectMap.get(entry.id);
+        objectMappingById.put(entry.id, item);
+        
+        LOG.debug("copied object map " + entry.id + " for " + item);
+        item.updateVersion();
+    }
+    
+    private void copyCollectionMapping(final Map<String, CollectionMapping> collMappingById, final Map<String, ObjectMapping> objectMappingById, HistoryEntry entry) {
+        
+        final CollectionMapping coll = collectionMap.get(entry.id);
+        collMappingById.put(entry.id, coll);
+        LOG.debug("copied collection map for " + coll);
+        
+        for (String elementId : coll) {
+            final ObjectMapping objMapping = objectMap.get(elementId);
+            
+            if (objMapping != null) {
+                objectMappingById.put(elementId, objMapping);
+                
+                LOG.debug("copied object map " + elementId + " for " + objMapping);
+                objMapping.updateVersion();
+            }
+        }
+    }
+
+    // ////////////////////////////////////////////////////
+    // Tasks 
+    // ////////////////////////////////////////////////////
+
     public Task getTask(final String taskId) {
         Task task = null;
         for (int i = crumbs.size() - 1; i >= 0; i--) {
@@ -276,52 +441,6 @@ public class Context {
         return task;
     }
 
-    public Request cancelTask(final Task task) {
-        if (task != null) {
-            endTask(task);
-        }
-
-        // REVIEW does this take us back to the right object?
-        final Crumb crumb = crumbs.get(crumbs.size() - 1);
-        return crumb.changeContext();
-    }
-
-    public void invalidate() {
-        isValid = false;
-    }
-
-    public boolean isValid() {
-        return isValid;
-    }
-
-    public boolean isLoggedIn() {
-        return session != null;
-    }
-
-    public String mapAction(final ObjectAction action) {
-        return addToMap(actionMap, action);
-    }
-
-    public String mapObject(final ObjectAdapter adapter) {
-        final ObjectMapping mapping = objectMapping(adapter);
-        return addToMap(objectMap, mapping);
-    }
-
-    private ObjectMapping objectMapping(final ObjectAdapter adapter) {
-        ObjectMapping mapping;
-        if (adapter.isTransient()) {
-            mapping = new TransientObjectMapping(adapter);
-        } else {
-            mapping = new PersistentObjectMapping(adapter);
-        }
-        return mapping;
-    }
-
-    public String mapCollection(final ObjectAdapter collection) {
-        final CollectionMapping map = new CollectionMapping(this, collection);
-        return addToMap(collectionMap, map);
-    }
-
     public void endTask(final Task task) {
         for (int i = crumbs.size() - 1; i >= 0; i--) {
             final Object crumb = crumbs.get(i);
@@ -336,28 +455,28 @@ public class Context {
         throw new IsisException("No crumb found for " + task);
     }
 
-    public Crumb[] getCrumbs() {
-        final int size = crumbs.size();
-        final Crumb[] taskList = new Crumb[size];
-        for (int i = 0; i < crumbs.size(); i++) {
-            taskList[i] = crumbs.get(i);
+
+    public Request cancelTask(final Task task) {
+        if (task != null) {
+            endTask(task);
         }
-        return taskList;
+
+        // REVIEW does this take us back to the right object?
+        final Crumb crumb = crumbs.get(crumbs.size() - 1);
+        return crumb.changeContext();
     }
 
-    public boolean[] isLinked() {
-        final int size = crumbs.size();
-        final boolean[] isLinked = new boolean[size];
-        for (int i = size - 1; i >= 0; i--) {
-            final boolean isTask = crumbs.elementAt(i) instanceof TaskCrumb;
-            isLinked[i] = i != size - 1;
-            if (isTask) {
-                break;
-            }
-        }
-        return isLinked;
+    private boolean isTask() {
+        final int index = crumbs.size() - 1;
+        return index >= 0 && crumbs.get(index) instanceof TaskCrumb;
     }
 
+    
+
+    // ////////////////////////////////////////////////////
+    // Messages 
+    // ////////////////////////////////////////////////////
+
     public List<String> getMessages() {
         return messages;
     }
@@ -386,73 +505,6 @@ public class Context {
         warnings.clear();
     }
 
-    private boolean isTask() {
-        final int index = crumbs.size() - 1;
-        return index >= 0 && crumbs.get(index) instanceof TaskCrumb;
-    }
-
-    public Request changeContext(final int id) {
-        while (crumbs.size() - 1 > id) {
-            crumbs.pop();
-        }
-        final Crumb c = crumbs.lastElement();
-        return c.changeContext();
-    }
-
-    public void setSession(final AuthenticationSession currentSession) {
-        this.session = currentSession;
-    }
-
-    public AuthenticationSession getSession() {
-        return session;
-    }
-
-    public void purge() {
-        actionMap.clear();
-        clearMessagesAndWarnings();
-
-        final Map newCollectionMap = new HashMap();
-        final Map newObjectMap = new HashMap();
-
-        final Iterator<HistoryEntry> elements = history.elements();
-        while (elements.hasNext()) {
-            final HistoryEntry entry = elements.next();
-            if (entry.type == HistoryEntry.OBJECT) {
-                final Object item = objectMap.get(entry.id);
-                newObjectMap.put(entry.id, item);
-                LOG.debug("copied object map " + entry.id + " for " + item);
-                ((ObjectMapping) item).updateVersion();
-            } else if (entry.type == HistoryEntry.COLLECTION) {
-                final CollectionMapping coll = collectionMap.get(entry.id);
-                newCollectionMap.put(entry.id, coll);
-                LOG.debug("copied collection map for " + coll);
-                final Enumeration e1 = coll.elements();
-                while (e1.hasMoreElements()) {
-                    final String id1 = (String) e1.nextElement();
-                    final Object item = objectMap.get(id1);
-                    if (item != null) {
-                        newObjectMap.put(id1, item);
-                        LOG.debug("copied object map " + id1 + " for " + item);
-                        ((ObjectMapping) item).updateVersion();
-                    }
-                }
-            }
-        }
-
-        collectionMap.clear();
-        collectionMap.putAll(newCollectionMap);
-        objectMap.clear();
-        objectMap.putAll(newObjectMap);
-        objectMap.putAll(serviceMap);
-    }
-
-    public void restoreAllObjectsToLoader() {
-        final Set oidSet = objectMap.entrySet();
-        for (final Iterator it = oidSet.iterator(); it.hasNext();) {
-            final ObjectMapping mapping = (ObjectMapping) ((Entry) it.next()).getValue();
-            mapping.restoreToLoader();
-        }
-    }
 
     public void listHistory(final Context context, final Block navigation) {
         history.listObjects(context, navigation);
@@ -466,19 +518,10 @@ public class Context {
         history.addCollection(idString);
     }
 
-    public void init() {
-        final AdapterManager adapterManager = IsisContext.getPersistenceSession().getAdapterManager();
-        final List<Object> services = getUserProfile().getPerspective().getServices();
-        for (final Object service : services) {
-            final ObjectAdapter serviceAdapter = adapterManager.adapterFor(service);
-            if (serviceAdapter == null) {
-                LOG.warn("unable to find service: " + service + "; skipping");
-                continue;
-            }
-            mapObject(serviceAdapter);
-        }
-        serviceMap.putAll(objectMap);
-    }
+    // ////////////////////////////////////////////////////
+    // 
+    // ////////////////////////////////////////////////////
+
 
     public void updateVersion(final ObjectAdapter adapter) {
         if (adapter.isTransient()) {
@@ -495,38 +538,91 @@ public class Context {
         }
     }
 
-    public void processChanges() {
-        final List<ObjectAdapter> disposedObjects = IsisContext.getUpdateNotifier().getDisposedObjects();
-        for (final ObjectAdapter adapter : disposedObjects) {
-            final ObjectMapping mapping = objectMapping(adapter);
-            if (objectMap.containsValue(mapping)) {
-                final String existingId = findExistingId(objectMap, mapping);
-                history.remove(existingId);
 
-                final ArrayList<Crumb> relatedCrumbs = new ArrayList<Crumb>();
-                for (final Crumb crumb : getCrumbs()) {
-                    /*
-                     * if (crumb.isFor(existingId)) { relatedCrumbs.add(crumb);
-                     * }
-                     */}
-                for (final Crumb crumb : relatedCrumbs) {
-                    crumbs.remove(crumb);
-                }
+    // ////////////////////////////////////////////////////
+    // Debug 
+    // ////////////////////////////////////////////////////
 
-                for (final CollectionMapping collection : collectionMap.values()) {
-                    collection.remove(existingId);
-                }
-                objectMap.remove(existingId);
-            }
+    public void debug(final DebugBuilder debug) {
+        debug.startSection("Web Session Context");
+        debug.appendAsHexln("hash", hashCode());
+        debug.appendln("session", session);
+        debug.appendln("is valid", isValid);
+        debug.appendln("next id", max);
+        debug.appendln("factory", componentFactory);
+        debug.appendln("is task", isTask());
+
+        debug.appendln("crumbs (" + crumbs.size() + ")");
+
+        debug.indent();
+        for (int i = 0; i < crumbs.size(); i++) {
+            final Crumb crumb = crumbs.get(i);
+            debug.appendln(i + 1 + ". " + crumb);
+            debug.indent();
+            crumb.debug(debug);
+            debug.unindent();
+        }
+        debug.unindent();
+
+        debug.startSection("Objects");
+        for (final String id : objectMap.keySet()) {
+            final ObjectMapping object = objectMap.get(id);
+            debug.appendln(id + " -> " + object.getOid());
+            debug.indent();
+            object.debug(debug);
+            debug.unindent();
+        }
+        debug.endSection();
+
+        debug.startSection("Collections");
+        for (final String id : collectionMap.keySet()) {
+            final CollectionMapping coll = collectionMap.get(id);
+            debug.appendln(id + " -> collection of " + coll.getElementSpecification().getPluralName());
+            coll.debug(debug);
+        }
+        debug.endSection();
+
+        debug.startSection("Actions");
+        debugMap(debug, actionMap);
+        debug.endSection();
+
+        debug.startSection("History");
+        history.debug(debug);
+        debug.endSection();
+
+        debug.endSection();
+    }
+
+    private void debugMap(final DebugBuilder debug, final Map<String,?> map) {
+        final Iterator<String> names = map.keySet().iterator();
+        while (names.hasNext()) {
+            final String name = names.next();
+            debug.appendln(name + " -> " + map.get(name));
         }
     }
 
+
     // ////////////////////////////////////////////////////
     // Dependencies (from context)
     // ////////////////////////////////////////////////////
 
-    private static UserProfile getUserProfile() {
+    protected UserProfile getUserProfile() {
         return IsisContext.getUserProfile();
     }
 
+    protected AdapterManager getAdapterManager() {
+        return getPersistenceSession().getAdapterManager();
+    }
+
+
+    protected PersistenceSession getPersistenceSession() {
+        return IsisContext.getPersistenceSession();
+    }
+
+    protected UpdateNotifier getUpdateNotifier() {
+        return IsisContext.getUpdateNotifier();
+    }
+
+
+
 }

Modified: incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/ObjectHistory.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/ObjectHistory.java?rev=1295480&r1=1295479&r2=1295480&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/ObjectHistory.java (original)
+++ incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/ObjectHistory.java Thu Mar  1 09:07:57 2012
@@ -33,7 +33,8 @@ import org.apache.isis.runtimes.dflt.run
 import org.apache.isis.viewer.html.component.Block;
 import org.apache.isis.viewer.html.component.Component;
 
-public class ObjectHistory {
+public class ObjectHistory implements Iterable<HistoryEntry> {
+
     private static final Logger LOG = Logger.getLogger(ObjectHistory.class);
     private static final int MAX = 8;
     private final List<HistoryEntry> history = new ArrayList<HistoryEntry>();
@@ -92,7 +93,7 @@ public class ObjectHistory {
         add(new HistoryEntry(idString, HistoryEntry.COLLECTION));
     }
 
-    public Iterator<HistoryEntry> elements() {
+    public Iterator<HistoryEntry> iterator() {
         return history.iterator();
     }
 

Modified: incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/ObjectMapping.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/ObjectMapping.java?rev=1295480&r1=1295479&r2=1295480&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/ObjectMapping.java (original)
+++ incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/ObjectMapping.java Thu Mar  1 09:07:57 2012
@@ -19,12 +19,14 @@
 
 package org.apache.isis.viewer.html.context;
 
+import java.io.Serializable;
+
 import org.apache.isis.core.commons.debug.DebugBuilder;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.oid.Oid;
 import org.apache.isis.core.metamodel.adapter.version.Version;
 
-public interface ObjectMapping {
+public interface ObjectMapping extends Serializable {
 
     Oid getOid();
 

Modified: incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/PersistentObjectMapping.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/PersistentObjectMapping.java?rev=1295480&r1=1295479&r2=1295480&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/PersistentObjectMapping.java (original)
+++ incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/PersistentObjectMapping.java Thu Mar  1 09:07:57 2012
@@ -30,6 +30,9 @@ import org.apache.isis.runtimes.dflt.run
 import org.apache.isis.runtimes.dflt.runtime.system.persistence.PersistenceSession;
 
 public class PersistentObjectMapping implements ObjectMapping {
+    
+    private static final long serialVersionUID = 1L;
+    
     private final Oid oid;
     private final ObjectSpecification specification;
     private Version version;

Modified: incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/TransientObjectMapping.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/TransientObjectMapping.java?rev=1295480&r1=1295479&r2=1295480&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/TransientObjectMapping.java (original)
+++ incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/context/TransientObjectMapping.java Thu Mar  1 09:07:57 2012
@@ -30,6 +30,9 @@ import org.apache.isis.runtimes.dflt.run
 import org.apache.isis.runtimes.dflt.runtime.system.persistence.PersistenceSession;
 
 public class TransientObjectMapping implements ObjectMapping {
+    
+    private static final long serialVersionUID = 1L;
+    
     private final Oid oid;
     private final Memento memento;
 

Modified: incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/servlet/AbstractHtmlViewerServlet.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/servlet/AbstractHtmlViewerServlet.java?rev=1295480&r1=1295479&r2=1295480&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/servlet/AbstractHtmlViewerServlet.java (original)
+++ incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/servlet/AbstractHtmlViewerServlet.java Thu Mar  1 09:07:57 2012
@@ -28,12 +28,21 @@ import org.apache.isis.runtimes.dflt.run
 import org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext;
 import org.apache.isis.viewer.html.PathBuilder;
 import org.apache.isis.viewer.html.PathBuilderDefault;
+import org.apache.isis.viewer.html.component.html.HtmlComponentFactory;
 
 public abstract class AbstractHtmlViewerServlet extends HttpServlet {
 
     private static final long serialVersionUID = 1L;
 
     private PathBuilder pathBuilder;
+    private HtmlComponentFactory componentFactory;
+
+    protected HtmlComponentFactory getHtmlComponentFactory() {
+        if(componentFactory == null) {
+            componentFactory = new HtmlComponentFactory(getPathBuilder());
+        }
+        return componentFactory;
+    }
 
     protected PathBuilder getPathBuilder() {
         if (pathBuilder != null) {
@@ -42,6 +51,7 @@ public abstract class AbstractHtmlViewer
         return pathBuilder = new PathBuilderDefault(getServletContext());
     }
 
+
     /**
      * Convenience.
      */

Modified: incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/servlet/ControllerServlet.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/servlet/ControllerServlet.java?rev=1295480&r1=1295479&r2=1295480&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/servlet/ControllerServlet.java (original)
+++ incubator/isis/trunk/framework/viewer/html/src/main/java/org/apache/isis/viewer/html/servlet/ControllerServlet.java Thu Mar  1 09:07:57 2012
@@ -32,7 +32,6 @@ import org.apache.log4j.Logger;
 
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
 import org.apache.isis.viewer.html.component.Page;
-import org.apache.isis.viewer.html.component.html.HtmlComponentFactory;
 import org.apache.isis.viewer.html.context.Context;
 import org.apache.isis.viewer.html.request.Request;
 import org.apache.isis.viewer.html.request.ServletRequest;
@@ -43,7 +42,7 @@ public class ControllerServlet extends A
     private static final long serialVersionUID = 1L;
     private static final Logger LOG = Logger.getLogger(ControllerServlet.class);
 
-    private String encoding = HtmlServletConstants.ENCODING_DEFAULT;
+    private String encoding;
     private WebController controller;
 
     // //////////////////////////////////////////////////////////////////
@@ -53,17 +52,16 @@ public class ControllerServlet extends A
     @Override
     public void init(final ServletConfig servletConfig) throws ServletException {
         super.init(servletConfig);
-        encoding = getConfiguration().getString(HtmlServletConstants.ENCODING_KEY, encoding);
+        encoding = getConfiguration().getString(HtmlServletConstants.ENCODING_KEY, HtmlServletConstants.ENCODING_DEFAULT);
 
-        controller = getNewWebController();
-        controller.setDebug(getConfiguration().getBoolean(HtmlServletConstants.DEBUG_KEY));
+        controller = new WebController(getPathBuilder());
+        
+        final boolean debugEnabled = getConfiguration().getBoolean(HtmlServletConstants.DEBUG_KEY);
+        controller.setDebug(debugEnabled);
+        
         controller.init();
     }
 
-    protected WebController getNewWebController() {
-        return new WebController(getPathBuilder());
-    }
-
     // //////////////////////////////////////////////////////////////////
     // doGet, doPost
     // //////////////////////////////////////////////////////////////////
@@ -100,48 +98,32 @@ public class ControllerServlet extends A
     }
 
     private Context getContextForRequest(final HttpServletRequest request) {
-        final AuthenticationSession authenticationSession = getAuthenticationSession();
-        Context context = (Context) authenticationSession.getAttribute(HtmlServletConstants.AUTHENTICATION_SESSION_CONTEXT_KEY);
+        final AuthenticationSession authSession = getAuthenticationSession();
+        Context context = (Context) authSession.getAttribute(HtmlServletConstants.AUTHENTICATION_SESSION_CONTEXT_KEY);
         if (context == null || !context.isValid()) {
-            // TODO reuse the component factory
-            context = new Context(getNewHtmlComponentFactory());
-            authenticationSession.setAttribute(HtmlServletConstants.AUTHENTICATION_SESSION_CONTEXT_KEY, context);
+            context = new Context(getHtmlComponentFactory());
+            authSession.setAttribute(HtmlServletConstants.AUTHENTICATION_SESSION_CONTEXT_KEY, context);
         }
         return context;
     }
 
-    protected HtmlComponentFactory getNewHtmlComponentFactory() {
-        return new HtmlComponentFactory(getPathBuilder());
-    }
-
     private void processRequest(final HttpServletRequest request, final HttpServletResponse response, final Request req, final Context context) throws IOException, ServletException {
         response.setContentType("text/html");
 
         // no need to check if logged in; the IsisSessionFilter would
         // have prevented us from getting here.
 
-        try {
-            // REVIEW: why was this commented out?
-            // SessionAccess.startRequest(context.getSession());
-            final Page page = controller.generatePage(context, req);
-            if (context.isValid()) {
-                if (controller.isDebug()) {
-                    controller.addDebug(page, req);
-                    addDebug(request, page);
-                }
-                PrintWriter writer;
-                writer = response.getWriter();
-                page.write(writer);
-            } else {
-                response.sendRedirect(getLogonPage());
-            }
-        } finally {
-            // REVIEW: why was this commented out?
-            // SessionAccess.endRequest(context.getSession());
-            if (!context.isLoggedIn()) {
-                final HttpSession httpSession = request.getSession(false);
-                LOG.info("dropping session: " + httpSession);
+        final Page page = controller.generatePage(context, req);
+        if (context.isValid()) {
+            if (controller.isDebug()) {
+                controller.addDebug(page, req);
+                addDebug(request, page);
             }
+            PrintWriter writer;
+            writer = response.getWriter();
+            page.write(writer);
+        } else {
+            response.sendRedirect(getLogonPage());
         }
     }
 

Added: incubator/isis/trunk/framework/viewer/html/src/test/java/org/apache/isis/viewer/html/context/ContextTest_serialization.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/html/src/test/java/org/apache/isis/viewer/html/context/ContextTest_serialization.java?rev=1295480&view=auto
==============================================================================
--- incubator/isis/trunk/framework/viewer/html/src/test/java/org/apache/isis/viewer/html/context/ContextTest_serialization.java (added)
+++ incubator/isis/trunk/framework/viewer/html/src/test/java/org/apache/isis/viewer/html/context/ContextTest_serialization.java Thu Mar  1 09:07:57 2012
@@ -0,0 +1,77 @@
+package org.apache.isis.viewer.html.context;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+
+import org.jmock.Expectations;
+import org.jmock.auto.Mock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.testsupport.jmock.JUnitRuleMockery2;
+import org.apache.isis.core.testsupport.jmock.JUnitRuleMockery2.Mode;
+import org.apache.isis.viewer.html.HtmlViewerConstants;
+import org.apache.isis.viewer.html.PathBuilder;
+import org.apache.isis.viewer.html.PathBuilderDefault;
+import org.apache.isis.viewer.html.component.ComponentFactory;
+import org.apache.isis.viewer.html.component.html.HtmlComponentFactory;
+
+public class ContextTest_serialization {
+
+    @Rule
+    public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_ONLY);
+    
+    @Mock
+    private IsisConfiguration isisConfiguration;
+    
+    private ComponentFactory factory;
+    private PathBuilder pathBuilder;
+    
+    private Context viewerContext;
+
+    @Before
+    public void setUp() throws Exception {
+        pathBuilder = new PathBuilderDefault("shtml");
+        context.checking(new Expectations() {
+            {
+                allowing(isisConfiguration).getString(HtmlViewerConstants.STYLE_SHEET);
+                will(returnValue("someStyleSheet.css"));
+
+                allowing(isisConfiguration).getString(HtmlViewerConstants.HEADER_FILE);
+                will(returnValue(null));
+
+                allowing(isisConfiguration).getString(HtmlViewerConstants.HEADER);
+                will(returnValue("<div></div>"));
+
+                allowing(isisConfiguration).getString(HtmlViewerConstants.FOOTER_FILE);
+                will(returnValue(null));
+
+                allowing(isisConfiguration).getString(HtmlViewerConstants.FOOTER);
+                will(returnValue("<div></div>"));
+            }
+        });
+
+        factory = new HtmlComponentFactory(pathBuilder, isisConfiguration);
+        
+        viewerContext = new Context(factory);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+    }
+
+    @Ignore // REVIEW: I'm not convinced that Context needs to be serializable, but I've seen Tomcat try to do so in some circumstances..
+    @Test
+    public void test() throws IOException {
+        OutputStream baos = new ByteArrayOutputStream();
+        final ObjectOutputStream objectOutputStream = new ObjectOutputStream(baos);
+        objectOutputStream.writeObject(viewerContext);
+    }
+
+}

Propchange: incubator/isis/trunk/framework/viewer/html/src/test/java/org/apache/isis/viewer/html/context/ContextTest_serialization.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/isis/trunk/framework/viewer/wicket/wicket-viewer/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication_init.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/wicket/wicket-viewer/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication_init.java?rev=1295480&r1=1295479&r2=1295480&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/wicket/wicket-viewer/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication_init.java (original)
+++ incubator/isis/trunk/framework/viewer/wicket/wicket-viewer/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication_init.java Thu Mar  1 09:07:57 2012
@@ -27,6 +27,7 @@ import com.google.inject.Injector;
 
 import org.apache.wicket.settings.IResourceSettings;
 import org.apache.wicket.settings.ISecuritySettings;
+import org.jmock.auto.Mock;
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Rule;
@@ -42,13 +43,15 @@ public class IsisWicketApplication_init 
 
     private IsisWicketApplication application;
 
+    @Mock
     private ISecuritySettings mockSecuritySettings;
+    @Mock
     private IResourceSettings mockResourceSettings;
 
     @Before
     public void setUp() throws Exception {
-        mockSecuritySettings = context.mockAndIgnoring(ISecuritySettings.class);
-        mockResourceSettings = context.mockAndIgnoring(IResourceSettings.class);
+        context.ignoring(mockSecuritySettings);
+        context.ignoring(mockResourceSettings);
 
         application = new IsisWicketApplication() {
             private static final long serialVersionUID = 1L;



Mime
View raw message