You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2012/10/01 11:57:30 UTC

svn commit: r1392259 - in /incubator/isis/trunk/framework: applib/src/main/java/org/apache/isis/applib/filter/ core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloa...

Author: danhaywood
Date: Mon Oct  1 09:57:29 2012
New Revision: 1392259

URL: http://svn.apache.org/viewvc?rev=1392259&view=rev
Log:
ISIS-232: facility to perform certain actions in bulk on collections

as a first pass, must be:
* contributed
* take 1 argument (the contributee)
* have no business rules (hide, disable, validate)
* return void

Added:
    incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/columns/ObjectAdapterToggleboxColumn.java
    incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ToggleButtonsPanel.css
    incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/
    incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedTogglebox.css
    incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedTogglebox.html
      - copied, changed from r1390596, incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTable.html
    incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedTogglebox.java
      - copied, changed from r1390596, incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ContainedButton.java
Modified:
    incubator/isis/trunk/framework/applib/src/main/java/org/apache/isis/applib/filter/Filters.java
    incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
    incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionFilters.java
    incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionImpl.java
    incubator/isis/trunk/framework/viewer/wicket/wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java
    incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTable.html
    incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTable.java
    incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/primitive/BooleanPanel.java
    incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ContainedButton.java
    incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuBuilder.java
    incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItem.java

Modified: incubator/isis/trunk/framework/applib/src/main/java/org/apache/isis/applib/filter/Filters.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/applib/src/main/java/org/apache/isis/applib/filter/Filters.java?rev=1392259&r1=1392258&r2=1392259&view=diff
==============================================================================
--- incubator/isis/trunk/framework/applib/src/main/java/org/apache/isis/applib/filter/Filters.java (original)
+++ incubator/isis/trunk/framework/applib/src/main/java/org/apache/isis/applib/filter/Filters.java Mon Oct  1 09:57:29 2012
@@ -29,7 +29,7 @@ public final class Filters {
             @Override
             public boolean accept(final T f) {
                 for(final Filter<T> filter: filters) {
-                    if(!filter.accept(f)) { 
+                    if(!filter.accept(f)) {     
                         return false;
                     }
                 }

Modified: incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java?rev=1392259&r1=1392258&r2=1392259&view=diff
==============================================================================
--- incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java (original)
+++ incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java Mon Oct  1 09:57:29 2012
@@ -84,8 +84,8 @@ public interface ObjectAction extends Ob
     ObjectSpecification getReturnType();
 
     /**
-     * Returns true if the represented action returns something, else returns
-     * false.
+     * Returns <tt>true</tt> if the represented action returns a non-void object, 
+     * else returns false.
      */
     boolean hasReturn();
 

Modified: incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionFilters.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionFilters.java?rev=1392259&r1=1392258&r2=1392259&view=diff
==============================================================================
--- incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionFilters.java (original)
+++ incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionFilters.java Mon Oct  1 09:57:29 2012
@@ -1,10 +1,18 @@
 package org.apache.isis.core.metamodel.spec.feature;
 
+import java.util.List;
+
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.filter.Filter;
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facetapi.FacetFilters;
+import org.apache.isis.core.metamodel.interactions.DisablingInteractionAdvisor;
+import org.apache.isis.core.metamodel.interactions.HidingInteractionAdvisor;
+import org.apache.isis.core.metamodel.interactions.ValidatingInteractionAdvisor;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 
 public class ObjectActionFilters {
 
@@ -20,11 +28,33 @@ public class ObjectActionFilters {
 
     public static Filter<ObjectAction> withId(final String actionId) {
         return new Filter<ObjectAction>(){
-    
             @Override
             public boolean accept(ObjectAction objectAction) {
                 return objectAction.getId().equals(actionId);
+            }
+        };
+    }
+
+    public static Filter<ObjectAction> withNoBusinessRules() {
+        return new Filter<ObjectAction>(){
+            @Override
+            public boolean accept(final ObjectAction objectAction) {
+                final List<Facet> hidingFacets = objectAction.getFacets(FacetFilters.isA(HidingInteractionAdvisor.class));
+                final List<Facet> disablingFacets = objectAction.getFacets(FacetFilters.isA(DisablingInteractionAdvisor.class));
+                final List<Facet> validatingFacets = objectAction.getFacets(FacetFilters.isA(ValidatingInteractionAdvisor.class));
+                return hidingFacets.isEmpty() && disablingFacets.isEmpty() && validatingFacets.isEmpty();
             }};
     }
 
+    public static Filter<ObjectAction> contributedAnd1ParamAndVoid() {
+        return new Filter<ObjectAction>(){
+            @Override
+            public boolean accept(final ObjectAction objectAction) {
+                boolean contributed = objectAction.isContributed();
+                boolean has1Param = objectAction.getParameterCount() == 1;
+                boolean hasReturn = objectAction.hasReturn();
+                return contributed && has1Param && !hasReturn;
+            }
+        };
+    }
 }

Modified: incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionImpl.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionImpl.java?rev=1392259&r1=1392258&r2=1392259&view=diff
==============================================================================
--- incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionImpl.java (original)
+++ incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionImpl.java Mon Oct  1 09:57:29 2012
@@ -133,9 +133,14 @@ public class ObjectActionImpl extends Ob
      */
     @Override
     public boolean hasReturn() {
-        return getReturnType() != null;
+        if(getReturnType() == null) {
+            // this shouldn't happen; return Type always defined, even if represents void.class
+            return false;
+        }
+        return getReturnType() != getSpecificationLookup().loadSpecification(void.class);
     }
 
+
     @Override
     public ObjectSpecification getOnType() {
         final ActionInvocationFacet facet = getActionInvocationFacet();

Modified: incubator/isis/trunk/framework/viewer/wicket/wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/wicket/wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java?rev=1392259&r1=1392258&r2=1392259&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/wicket/wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java (original)
+++ incubator/isis/trunk/framework/viewer/wicket/wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java Mon Oct  1 09:57:29 2012
@@ -20,6 +20,7 @@
 package org.apache.isis.viewer.wicket.model.models;
 
 import java.io.Serializable;
+import java.util.Collections;
 import java.util.List;
 
 import com.google.common.collect.Iterables;
@@ -137,6 +138,11 @@ public class EntityCollectionModel exten
     private List<ObjectAdapterMemento> mementoList;
 
     /**
+     * Populated only if {@link Type#STANDALONE}.
+     */
+    private List<ObjectAdapterMemento> toggledMementosList;
+
+    /**
      * Populated only if {@link Type#PARENTED}.
      */
     private ObjectAdapterMemento parentObjectAdapterMemento;
@@ -155,6 +161,7 @@ public class EntityCollectionModel exten
         this.typeOf = typeOf;
         this.mementoList = mementoList;
         this.pageSize = pageSize;
+        this.toggledMementosList = Lists.newArrayList();
     }
 
     private EntityCollectionModel(final ObjectAdapter adapter, final OneToManyAssociation collection) {
@@ -249,4 +256,24 @@ public class EntityCollectionModel exten
     public static Iterable<Object> asIterable(final ObjectAdapter resultAdapter) {
         return (Iterable<Object>) resultAdapter.getObject();
     }
+
+    
+    public void toggleSelectionOn(ObjectAdapter selectedAdapter) {
+        ObjectAdapterMemento selectedAsMemento = ObjectAdapterMemento.createOrNull(selectedAdapter);
+        
+        // try to remove; if couldn't, then mustn't have been in there, in which case add.
+        boolean removed = toggledMementosList.remove(selectedAsMemento);
+        if(!removed) {
+            toggledMementosList.add(selectedAsMemento);
+        }
+    }
+    
+    public List<ObjectAdapterMemento> getToggleMementosList() {
+        return Collections.unmodifiableList(this.toggledMementosList);
+    }
+
+    public void clearToggleMementosList() {
+        this.toggledMementosList.clear();
+    }
+    
 }

Modified: incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTable.html
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTable.html?rev=1392259&r1=1392258&r2=1392259&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTable.html (original)
+++ incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTable.html Mon Oct  1 09:57:29 2012
@@ -20,6 +20,17 @@
 <html>
 	<body>
 		<wicket:panel>
+			<div class="actions panel">				
+  				<table>
+      	   			<tbody>
+      	      			<tr>
+      						<td>
+      			      			<span class="entityActions" wicket:id="entityActions"/>
+      		      			</td>
+      	     			</tr>
+           			</tbody>
+   			   </table>
+		    </div>
 			<table class="collectionContentsAsAjaxTable" cellspacing="0" wicket:id="table">[table]</table>
 		</wicket:panel>
 	</body>

Modified: incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTable.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTable.java?rev=1392259&r1=1392258&r2=1392259&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTable.java (original)
+++ incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTable.java Mon Oct  1 09:57:29 2012
@@ -23,24 +23,39 @@ import java.util.List;
 
 import com.google.common.collect.Lists;
 
+import org.apache.wicket.Component;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
 import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
 import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
+import org.apache.wicket.markup.html.link.AbstractLink;
 import org.apache.wicket.model.Model;
 
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.filter.Filter;
 import org.apache.isis.applib.filter.Filters;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager.ConcurrencyChecking;
+import org.apache.isis.core.metamodel.spec.ActionType;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.ObjectActionContainer.Contributed;
+import org.apache.isis.core.metamodel.spec.feature.ObjectActionFilters;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAssociationFilters;
 import org.apache.isis.viewer.wicket.model.common.SelectionHandler;
+import org.apache.isis.viewer.wicket.model.mementos.ActionMemento;
+import org.apache.isis.viewer.wicket.model.mementos.ObjectAdapterMemento;
 import org.apache.isis.viewer.wicket.model.models.EntityCollectionModel;
 import org.apache.isis.viewer.wicket.ui.components.collectioncontents.ajaxtable.columns.ColumnAbstract;
 import org.apache.isis.viewer.wicket.ui.components.collectioncontents.ajaxtable.columns.ObjectAdapterPropertyColumn;
 import org.apache.isis.viewer.wicket.ui.components.collectioncontents.ajaxtable.columns.ObjectAdapterSelectColumn;
 import org.apache.isis.viewer.wicket.ui.components.collectioncontents.ajaxtable.columns.ObjectAdapterTitleColumn;
+import org.apache.isis.viewer.wicket.ui.components.collectioncontents.ajaxtable.columns.ObjectAdapterToggleboxColumn;
+import org.apache.isis.viewer.wicket.ui.components.widgets.cssmenu.CssMenuBuilder;
+import org.apache.isis.viewer.wicket.ui.components.widgets.cssmenu.CssMenuLinkFactory;
+import org.apache.isis.viewer.wicket.ui.components.widgets.cssmenu.CssMenuPanel;
 import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
 
 /**
@@ -50,7 +65,12 @@ import org.apache.isis.viewer.wicket.ui.
 public class CollectionContentsAsAjaxTable extends PanelAbstract<EntityCollectionModel> {
 
     private static final long serialVersionUID = 1L;
-    
+
+    private static final String ID_TABLE = "table";
+    private static final String ID_ENTITY_ACTIONS = "entityActions";
+
+    private AjaxFallbackDefaultDataTable<ObjectAdapter,String> dataTable;
+
     public CollectionContentsAsAjaxTable(final String id, final EntityCollectionModel model) {
         super(id, model);
 
@@ -60,18 +80,84 @@ public class CollectionContentsAsAjaxTab
     private void buildGui() {
         final EntityCollectionModel model = getModel();
 
+        buildEntityActionsGui();
+        
         final List<IColumn<ObjectAdapter,String>> columns = Lists.newArrayList();
 
+        addToggleboxColumnIfRequired(columns);
         addTitleColumn(columns);
         addPropertyColumnsIfRequired(columns);
         addSelectedButtonIfRequired(columns);
 
         final SortableDataProvider<ObjectAdapter,String> dataProvider = new CollectionContentsSortableDataProvider(model);
-        final AjaxFallbackDefaultDataTable<ObjectAdapter,String> dataTable = new AjaxFallbackDefaultDataTable<ObjectAdapter,String>("table", columns, dataProvider, model.getPageSize());
+        dataTable = new AjaxFallbackDefaultDataTable<ObjectAdapter,String>(ID_TABLE, columns, dataProvider, model.getPageSize());
         add(dataTable);
     }
 
-    private void addTitleColumn(final List<IColumn<ObjectAdapter,String>> columns) {
+    private void addToggleboxColumnIfRequired(final List<IColumn<ObjectAdapter,String>> columns) {
+        final EntityCollectionModel model = getModel();
+        
+        if(model.isStandalone()) {
+            columns.add(new ObjectAdapterToggleboxColumn(new SelectionHandler() {
+                
+                private static final long serialVersionUID = 1L;
+
+                @Override
+                public void onSelected(final Component context, final ObjectAdapter selectedAdapter) {
+                    model.toggleSelectionOn(selectedAdapter);
+                }
+            }));
+        }
+    }
+
+    private void buildEntityActionsGui() {
+        final EntityCollectionModel model = getModel();
+        final ObjectSpecification typeSpec = model.getTypeOfSpecification();
+        
+        @SuppressWarnings("unchecked")
+        final List<ObjectAction> userActions = typeSpec.getObjectActions(ActionType.USER, Contributed.INCLUDED, 
+                Filters.and(
+                        ObjectActionFilters.withNoBusinessRules(), ObjectActionFilters.contributedAnd1ParamAndVoid()
+                ));
+
+        final CssMenuLinkFactory linkFactory = new CssMenuLinkFactory(){
+
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public LinkAndLabel newLink(final ObjectAdapterMemento adapter, final ObjectAction objectAction, final String linkId) {
+                final ActionMemento actionMemento = new ActionMemento(objectAction);
+                AbstractLink link = new AjaxLink<Void>(linkId) {
+
+                    private static final long serialVersionUID = 1L;
+
+                    @Override
+                    public void onClick(AjaxRequestTarget target) {
+                        final ObjectAction objectAction = actionMemento.getAction();
+                        for(ObjectAdapterMemento adapterMemento: model.getToggleMementosList()) {
+                            objectAction.execute(adapter.getObjectAdapter(ConcurrencyChecking.NO_CHECK), new ObjectAdapter[]{adapterMemento.getObjectAdapter(ConcurrencyChecking.CHECK)});
+                        }
+                        model.clearToggleMementosList();
+                        target.add(dataTable);
+                    }
+                };
+                return new LinkAndLabel(link, objectAction.getName());
+            }
+        };
+
+        if(!userActions.isEmpty()) {
+            final CssMenuBuilder cssMenuBuilder = new CssMenuBuilder(null, getServiceAdapters(), userActions, linkFactory);
+            // TODO: i18n
+            final CssMenuPanel cssMenuPanel = cssMenuBuilder.buildPanel(ID_ENTITY_ACTIONS, "Actions");
+
+            this.addOrReplace(cssMenuPanel);
+        } else {
+            permanentlyHide(ID_ENTITY_ACTIONS);
+        }
+    }
+
+
+    private static void addTitleColumn(final List<IColumn<ObjectAdapter,String>> columns) {
         columns.add(new ObjectAdapterTitleColumn());
     }
 

Added: incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/columns/ObjectAdapterToggleboxColumn.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/columns/ObjectAdapterToggleboxColumn.java?rev=1392259&view=auto
==============================================================================
--- incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/columns/ObjectAdapterToggleboxColumn.java (added)
+++ incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/columns/ObjectAdapterToggleboxColumn.java Mon Oct  1 09:57:29 2012
@@ -0,0 +1,53 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.viewer.wicket.ui.components.collectioncontents.ajaxtable.columns;
+
+import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.model.IModel;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.viewer.wicket.model.common.SelectionHandler;
+import org.apache.isis.viewer.wicket.ui.components.widgets.checkbox.ContainedTogglebox;
+
+public final class ObjectAdapterToggleboxColumn extends ColumnAbstract<ObjectAdapter> {
+
+    private static final long serialVersionUID = 1L;
+
+    private final SelectionHandler handler;
+
+    public ObjectAdapterToggleboxColumn(final SelectionHandler handler) {
+        super("");
+        this.handler = handler;
+    }
+
+    @Override
+    public void populateItem(final Item<ICellPopulator<ObjectAdapter>> cellItem, final String componentId, final IModel<ObjectAdapter> rowModel) {
+        cellItem.add(new ContainedTogglebox(componentId) {
+            private static final long serialVersionUID = 1L;
+            @Override
+            public void onSubmit() {
+                final IModel<ObjectAdapter> o = rowModel;
+                final ObjectAdapter selectedAdapter = o.getObject();
+                handler.onSelected(this, selectedAdapter);
+            }
+        });
+    }
+}
\ No newline at end of file

Modified: incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/primitive/BooleanPanel.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/primitive/BooleanPanel.java?rev=1392259&r1=1392258&r2=1392259&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/primitive/BooleanPanel.java (original)
+++ incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/primitive/BooleanPanel.java Mon Oct  1 09:57:29 2012
@@ -95,7 +95,7 @@ public class BooleanPanel extends Scalar
             public Boolean getObject() {
                 final ScalarModel model = getModel();
                 final ObjectAdapter adapter = model.getObject();
-                return (Boolean) adapter.getObject();
+                return adapter != null? (Boolean) adapter.getObject(): false;
             }
 
             @Override

Modified: incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ContainedButton.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ContainedButton.java?rev=1392259&r1=1392258&r2=1392259&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ContainedButton.java (original)
+++ incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ContainedButton.java Mon Oct  1 09:57:29 2012
@@ -29,7 +29,6 @@ import org.apache.wicket.ajax.markup.htm
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.form.Button;
 import org.apache.wicket.markup.html.form.Form;
-import org.apache.wicket.markup.html.internal.HtmlHeaderContainer;
 import org.apache.wicket.model.Model;
 
 import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
@@ -49,13 +48,13 @@ public class ContainedButton extends Pan
     private final List<Component> componentsToRerender = Lists.newArrayList();
 
     public ContainedButton(final String id, final String caption) {
-        super(id);
+        super(id, Model.of(caption));
 
         final WebMarkupContainer markupContainer = new WebMarkupContainer(ID_CONTAINER);
         add(markupContainer);
         final Form<Object> form = new Form<Object>(ID_FORM);
         markupContainer.add(form);
-        button = new AjaxButton(ID_BUTTON, Model.of(caption)) {
+        button = new AjaxButton(ID_BUTTON, getModel()) {
             private static final long serialVersionUID = 1L;
 
             @Override
@@ -91,9 +90,4 @@ public class ContainedButton extends Pan
      */
     public void onSubmit() {
     }
-
-    @Override
-    public void renderHead(final HtmlHeaderContainer container) {
-        super.renderHead(container);
-    }
 }

Added: incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ToggleButtonsPanel.css
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ToggleButtonsPanel.css?rev=1392259&view=auto
==============================================================================
--- incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ToggleButtonsPanel.css (added)
+++ incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ToggleButtonsPanel.css Mon Oct  1 09:57:29 2012
@@ -0,0 +1,18 @@
+/*
+ *  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.
+ */

Added: incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedTogglebox.css
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedTogglebox.css?rev=1392259&view=auto
==============================================================================
--- incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedTogglebox.css (added)
+++ incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedTogglebox.css Mon Oct  1 09:57:29 2012
@@ -0,0 +1,25 @@
+/*
+ *  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.
+ */
+span.containedButton {
+	display: inline;
+}
+
+.containedButton form {
+	display: inline;
+}

Copied: incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedTogglebox.html (from r1390596, incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTable.html)
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedTogglebox.html?p2=incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedTogglebox.html&p1=incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTable.html&r1=1390596&r2=1392259&rev=1392259&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTable.html (original)
+++ incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedTogglebox.html Mon Oct  1 09:57:29 2012
@@ -1,26 +1,30 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-         http://www.apache.org/licenses/LICENSE-2.0
-         
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<html>
-	<body>
-		<wicket:panel>
-			<table class="collectionContentsAsAjaxTable" cellspacing="0" wicket:id="table">[table]</table>
-		</wicket:panel>
-	</body>
-</html>
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+  
+         http://www.apache.org/licenses/LICENSE-2.0
+         
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<html>
+	<body>
+		<wicket:panel>
+			<span wicket:id="container" class="containedTogglebox">
+				<form wicket:id="form">
+					<input type="checkbox" wicket:id="togglebox" />
+				</form>
+			</span>
+		</wicket:panel>
+	</body>
+</html>

Copied: incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedTogglebox.java (from r1390596, incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ContainedButton.java)
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedTogglebox.java?p2=incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedTogglebox.java&p1=incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ContainedButton.java&r1=1390596&r2=1392259&rev=1392259&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ContainedButton.java (original)
+++ incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedTogglebox.java Mon Oct  1 09:57:29 2012
@@ -1,99 +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.wicket.ui.components.widgets.buttons;
-
-import java.util.List;
-
-import com.google.common.collect.Lists;
-
-import org.apache.wicket.Component;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.markup.html.form.AjaxButton;
-import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.markup.html.form.Button;
-import org.apache.wicket.markup.html.form.Form;
-import org.apache.wicket.markup.html.internal.HtmlHeaderContainer;
-import org.apache.wicket.model.Model;
-
-import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
-
-/**
- * A button contained within its own form.
- */
-public class ContainedButton extends PanelAbstract<Model<String>> {
-
-    private static final long serialVersionUID = 1L;
-
-    private static final String ID_CONTAINER = "container";
-    private static final String ID_FORM = "form";
-    private static final String ID_BUTTON = "button";
-
-    private final Button button;
-    private final List<Component> componentsToRerender = Lists.newArrayList();
-
-    public ContainedButton(final String id, final String caption) {
-        super(id);
-
-        final WebMarkupContainer markupContainer = new WebMarkupContainer(ID_CONTAINER);
-        add(markupContainer);
-        final Form<Object> form = new Form<Object>(ID_FORM);
-        markupContainer.add(form);
-        button = new AjaxButton(ID_BUTTON, Model.of(caption)) {
-            private static final long serialVersionUID = 1L;
-
-            @Override
-            protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
-                setDefaultFormProcessing(false);
-                ContainedButton.this.onSubmit();
-                if (target != null) {
-                    for (final Component component : componentsToRerender) {
-                        //target.addComponent(component);
-                        target.add(component);
-                    }
-                }
-            }
-        };
-        form.add(button);
-    }
-
-    public void addComponentToRerender(final Component component) {
-        component.setOutputMarkupPlaceholderTag(true);
-        componentsToRerender.add(component);
-    }
-
-    public void setCaption(final String string) {
-        button.setModelValue(new String[] { string });
-    }
-
-    public void setLabel(final Model<String> labelModel) {
-        button.setLabel(labelModel);
-    }
-
-    /**
-     * Hook method for (typically anonymous) subclasses to override.
-     */
-    public void onSubmit() {
-    }
-
-    @Override
-    public void renderHead(final HtmlHeaderContainer container) {
-        super.renderHead(container);
-    }
-}
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.viewer.wicket.ui.components.widgets.checkbox;
+
+import java.util.List;
+
+import com.google.common.collect.Lists;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.model.Model;
+
+import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
+
+/**
+ * A button contained within its own form.
+ */
+public class ContainedTogglebox extends PanelAbstract<Model<Boolean>> {
+
+    private static final long serialVersionUID = 1L;
+
+    private static final String ID_CONTAINER = "container";
+    private static final String ID_FORM = "form";
+    private static final String ID_TOGGLEBOX = "togglebox";
+
+    private final AjaxCheckBox checkbox;
+    private final List<Component> componentsToRerender = Lists.newArrayList();
+
+    public ContainedTogglebox(final String id) {
+        super(id);
+
+        final WebMarkupContainer markupContainer = new WebMarkupContainer(ID_CONTAINER);
+        add(markupContainer);
+        final Form<Object> form = new Form<Object>(ID_FORM);
+        markupContainer.add(form);
+        
+        checkbox = new AjaxCheckBox(ID_TOGGLEBOX, Model.of(false)) {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            protected void onUpdate(AjaxRequestTarget target) {
+                ContainedTogglebox.this.onSubmit();
+            }
+        };
+        form.add(checkbox);
+    }
+
+    public void addComponentToRerender(final Component component) {
+        component.setOutputMarkupPlaceholderTag(true);
+        componentsToRerender.add(component);
+    }
+ 
+    /**
+     * Hook method for (typically anonymous) subclasses to override.
+     */
+    public void onSubmit() {
+    }
+}

Modified: incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuBuilder.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuBuilder.java?rev=1392259&r1=1392258&r2=1392259&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuBuilder.java (original)
+++ incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuBuilder.java Mon Oct  1 09:57:29 2012
@@ -130,6 +130,9 @@ public class CssMenuBuilder {
         }
 
         final ObjectAdapterMemento serviceAdapterMemento = determineAdapterFor(contributedAction);
+        if(serviceAdapterMemento == null) {
+            return;
+        }
 
         final Builder subMenuItemBuilder = parent.newSubMenuItem(serviceAdapterMemento, contributedAction, cssMenuLinkFactory);
         if (subMenuItemBuilder != null) {

Modified: incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItem.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItem.java?rev=1392259&r1=1392258&r2=1392259&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItem.java (original)
+++ incubator/isis/trunk/framework/viewer/wicket/wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItem.java Mon Oct  1 09:57:29 2012
@@ -197,24 +197,24 @@ public class CssMenuItem implements Seri
      * @return the builder, else <tt>null</tt> if the action is not visible for
      *         the current user.
      */
-    public Builder newSubMenuItem(final ObjectAdapterMemento adapterMemento, final ObjectAction noAction, final CssMenuLinkFactory cssMenuLinkFactory) {
+    public Builder newSubMenuItem(final ObjectAdapterMemento adapterMemento, final ObjectAction objectAction, final CssMenuLinkFactory cssMenuLinkFactory) {
 
         final AuthenticationSession session = getAuthenticationSession();
 
         final CssMenuItem parentMenuItem = this;
 
         final ObjectAdapter adapter = adapterMemento.getObjectAdapter(ConcurrencyChecking.CHECK);
-        final Consent visibility = noAction.isVisible(session, adapter, where);
+        final Consent visibility = objectAction.isVisible(session, adapter, where);
         if (visibility.isVetoed()) {
             return null;
         }
 
-        final LinkAndLabel linkAndLabel = cssMenuLinkFactory.newLink(adapterMemento, noAction, PageAbstract.ID_MENU_LINK);
+        final LinkAndLabel linkAndLabel = cssMenuLinkFactory.newLink(adapterMemento, objectAction, PageAbstract.ID_MENU_LINK);
 
         final AbstractLink link = linkAndLabel.getLink();
         final String actionLabel = linkAndLabel.getLabel();
 
-        final Consent usability = noAction.isUsable(session, adapter, where);
+        final Consent usability = objectAction.isUsable(session, adapter, where);
         final String reasonDisabledIfAny = usability.getReason();
 
         return parentMenuItem.newSubMenuItem(actionLabel).link(link).enabled(reasonDisabledIfAny);