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 2015/01/07 01:54:37 UTC
isis git commit: ISIS-985: new VisibilityContext at object level,
fired when rendering objects in table (and also an object on a page),
in support of multi-tenancy (as implemented by isisaddons' security module).
Repository: isis
Updated Branches:
refs/heads/ISIS-985 f0e895a3f -> d1ed04ece
ISIS-985: new VisibilityContext at object level, fired when rendering objects in table (and also an object on a page), in support of multi-tenancy (as implemented by isisaddons' security module).
Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/d1ed04ec
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/d1ed04ec
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/d1ed04ec
Branch: refs/heads/ISIS-985
Commit: d1ed04eceb8bd0799801dda24ce9b4b82125e38d
Parents: f0e895a
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Wed Jan 7 00:54:30 2015 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Wed Jan 7 00:54:30 2015 +0000
----------------------------------------------------------------------
.../CollectionContentsSortableDataProvider.java | 82 ++++++++++++--------
.../entity/properties/EntityPropertiesForm.java | 6 +-
.../wicket/ui/pages/entity/EntityPage.java | 47 +++++++++--
.../standard/AuthorizationManagerStandard.java | 6 ++
4 files changed, 100 insertions(+), 41 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/isis/blob/d1ed04ec/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsSortableDataProvider.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsSortableDataProvider.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsSortableDataProvider.java
index 985da69..8b9641c 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsSortableDataProvider.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsSortableDataProvider.java
@@ -59,19 +59,6 @@ public class CollectionContentsSortableDataProvider extends SortableDataProvider
}
@Override
- public Iterator<ObjectAdapter> iterator(final long first, final long count) {
- final List<ObjectAdapter> unfilteredAdapters = model.getObject();
-
- final List<ObjectAdapter> filteredAdapters = Lists.newArrayList(Iterables.filter(unfilteredAdapters, ignoreHidden()));
-
- List<ObjectAdapter> adapters = sortedIfRequired(filteredAdapters, this.getSort());
-
- final int from = (int) first;
- final int toIndex = Math.min((int) (first + count), adapters.size());
- return adapters.subList(from, toIndex).iterator();
- }
-
- @Override
public IModel<ObjectAdapter> model(final ObjectAdapter adapter) {
return new EntityModel(adapter);
}
@@ -87,28 +74,62 @@ public class CollectionContentsSortableDataProvider extends SortableDataProvider
model.detach();
}
-
- private List<ObjectAdapter> sortedIfRequired(List<ObjectAdapter> adapters, final SortParam<String> sort) {
+ @Override
+ public Iterator<ObjectAdapter> iterator(final long first, final long count) {
+
+ final List<ObjectAdapter> adapters = model.getObject();
+
+ final Iterable<ObjectAdapter> visibleAdapters =
+ Iterables.filter(adapters, ignoreHidden());
+
+ // need to create a list from the iterable, then back to an iterable
+ // because guava's Ordering class doesn't support sorting of iterable -> iterable
+ final List<ObjectAdapter> sortedVisibleAdapters = sortedCopy(visibleAdapters, getSort());
+ final List<ObjectAdapter> pagedAdapters = subList(first, count, sortedVisibleAdapters);
+ return pagedAdapters.iterator();
+ }
+
+ private static List<ObjectAdapter> subList(
+ final long first,
+ final long count,
+ final List<ObjectAdapter> objectAdapters) {
+
+ final int fromIndex = (int) first;
+ // if adapters where filter out (as invisible), then make sure don't run off the end
+ final int toIndex = Math.min((int) (first + count), objectAdapters.size());
+
+ return objectAdapters.subList(fromIndex, toIndex);
+ }
+
+ private List<ObjectAdapter> sortedCopy(
+ final Iterable<ObjectAdapter> adapters,
+ final SortParam<String> sort) {
+
+ final ObjectAssociation sortProperty = lookupAssociationFor(sort);
+ if(sortProperty == null) {
+ return Lists.newArrayList(adapters);
+ }
+
+ final Ordering<ObjectAdapter> ordering =
+ orderingBy(sortProperty, sort.isAscending());
+ return ordering.sortedCopy(adapters);
+ }
+
+ private ObjectAssociation lookupAssociationFor(final SortParam<String> sort) {
if(sort == null) {
- return adapters;
+ return null;
}
-
+
final ObjectSpecification elementSpec = model.getTypeOfSpecification();
-
final String sortPropertyId = sort.getProperty();
- try {
- final ObjectAssociation sortProperty = elementSpec.getAssociation(sortPropertyId);
- if(sortProperty == null) {
- return adapters;
- }
-
- Ordering<ObjectAdapter> ordering = orderingBy(sortProperty, sort.isAscending());
- return ordering.sortedCopy(adapters);
+ try {
+ // might be null, or throw ex
+ return elementSpec.getAssociation(sortPropertyId);
} catch(ObjectSpecificationException ex) {
// eg invalid propertyId
- return adapters;
+ return null;
}
}
@@ -132,8 +153,7 @@ public class CollectionContentsSortableDataProvider extends SortableDataProvider
Where.ALL_TABLES);
}
-
- public static Ordering<ObjectAdapter> orderingBy(final ObjectAssociation sortProperty, final boolean ascending) {
+ private static Ordering<ObjectAdapter> orderingBy(final ObjectAssociation sortProperty, final boolean ascending) {
final Ordering<ObjectAdapter> ordering = new Ordering<ObjectAdapter>(){
@Override
@@ -150,7 +170,7 @@ public class CollectionContentsSortableDataProvider extends SortableDataProvider
return ascending?ordering:ordering.reverse();
}
- public static Ordering<ObjectAdapter> ORDERING_BY_NATURAL = new Ordering<ObjectAdapter>(){
+ private static Ordering<ObjectAdapter> ORDERING_BY_NATURAL = new Ordering<ObjectAdapter>(){
@Override
public int compare(final ObjectAdapter p, final ObjectAdapter q) {
final Object pPojo = p.getObject();
@@ -168,8 +188,6 @@ public class CollectionContentsSortableDataProvider extends SortableDataProvider
}
};
-
-
// //////////////////////////////////////
protected AuthenticationSession getAuthenticationSession() {
http://git-wip-us.apache.org/repos/asf/isis/blob/d1ed04ec/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityPropertiesForm.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityPropertiesForm.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityPropertiesForm.java
index b7f1127..cb2dc45 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityPropertiesForm.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityPropertiesForm.java
@@ -122,7 +122,11 @@ public class EntityPropertiesForm extends FormAbstract<ObjectAdapter> implements
private boolean renderedFirstField;
- public EntityPropertiesForm(final String id, final EntityModel entityModel, final Component owningPanel) {
+ public EntityPropertiesForm(
+ final String id,
+ final EntityModel entityModel,
+ final Component owningPanel) {
+
super(id, entityModel);
this.owningPanel = owningPanel; // for repainting
http://git-wip-us.apache.org/repos/asf/isis/blob/d1ed04ec/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/entity/EntityPage.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/entity/EntityPage.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/entity/EntityPage.java
index 5ca6c24..64a18cc 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/entity/EntityPage.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/entity/EntityPage.java
@@ -29,6 +29,12 @@ import org.apache.isis.core.commons.authentication.AuthenticationSession;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager.ConcurrencyChecking;
import org.apache.isis.core.metamodel.adapter.version.ConcurrencyException;
+import org.apache.isis.core.metamodel.consent.InteractionInvocationMethod;
+import org.apache.isis.core.metamodel.consent.InteractionResult;
+import org.apache.isis.core.metamodel.deployment.DeploymentCategory;
+import org.apache.isis.core.metamodel.interactions.InteractionUtils;
+import org.apache.isis.core.metamodel.interactions.ObjectVisibilityContext;
+import org.apache.isis.core.metamodel.interactions.VisibilityContext;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.feature.Contributed;
import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
@@ -72,14 +78,14 @@ public class EntityPage extends PageAbstract {
* Ensure that any {@link ConcurrencyException} that might have occurred already
* (eg from an action invocation) is show.
*/
- public EntityPage(ObjectAdapter adapter, ConcurrencyException exIfAny) {
+ public EntityPage(final ObjectAdapter adapter, final ConcurrencyException exIfAny) {
this(new PageParameters(), newEntityModel(adapter, exIfAny));
}
private static EntityModel newEntityModel(
final ObjectAdapter adapter,
final ConcurrencyException exIfAny) {
- EntityModel model = new EntityModel(adapter);
+ final EntityModel model = new EntityModel(adapter);
model.setException(exIfAny);
return model;
}
@@ -96,7 +102,7 @@ public class EntityPage extends PageAbstract {
try {
// check object still exists
objectAdapter = entityModel.getObject();
- } catch(RuntimeException ex) {
+ } catch(final RuntimeException ex) {
removeAnyBookmark(model);
removeAnyBreadcrumb(model);
@@ -104,7 +110,12 @@ public class EntityPage extends PageAbstract {
throw new ObjectMember.AuthorizationException(ex);
}
- // check that at least one property of the entity can be viewed.
+ // check that the entity overall can be viewed.
+ if(!isVisible(objectAdapter)) {
+ throw new ObjectMember.AuthorizationException();
+ }
+
+ // belt-n-braces: check that at least one property of the entity can be viewed.
final AuthenticationSession session = getAuthenticationSession();
final ObjectSpecification specification = objectAdapter.getSpecification();
final List<ObjectAssociation> visibleAssociation = specification.getAssociations(Contributed.INCLUDED, ObjectAssociation.Filters.dynamicallyVisible(session, objectAdapter, Where.NOWHERE));
@@ -114,7 +125,7 @@ public class EntityPage extends PageAbstract {
}
- // this is a work-around for JRebel integration...
+ // the next bit is a work-around for JRebel integration...
// ... even though the IsisJRebelPlugin calls invalidateCache, it seems that there is
// some caching elsewhere in the Wicket viewer meaning that stale metadata is referenced.
// doing an additional call here seems to be sufficient, though not exactly sure why... :-(
@@ -123,7 +134,7 @@ public class EntityPage extends PageAbstract {
}
if(titleString == null) {
- String titleStr = objectAdapter.titleString(null);
+ final String titleStr = objectAdapter.titleString(null);
setTitle(titleStr);
}
@@ -135,6 +146,7 @@ public class EntityPage extends PageAbstract {
addBookmarkedPages();
+
// TODO mgrigorov: Zero Clipboard has been moved to EntityIconAndTitlePanel where the entity model is available.
// Is this still needed for something else ?!
//
@@ -142,14 +154,30 @@ public class EntityPage extends PageAbstract {
send(this, Broadcast.BREADTH, new IsisUiHintEvent(entityModel, null));
}
+ private boolean isVisible(final ObjectAdapter input) {
+ final InteractionResult visibleResult = InteractionUtils.isVisibleResult(input.getSpecification(), createVisibleInteractionContext(input));
+ return visibleResult.isNotVetoing();
+ }
+
+ private VisibilityContext<?> createVisibleInteractionContext(final ObjectAdapter objectAdapter) {
+ return new ObjectVisibilityContext(
+ getDeploymentCategory(),
+ getAuthenticationSession(),
+ InteractionInvocationMethod.BY_USER,
+ objectAdapter,
+ objectAdapter.getSpecification().getIdentifier(),
+ Where.OBJECT_FORMS);
+ }
+
- private void addBreadcrumb(EntityModel entityModel) {
+
+ private void addBreadcrumb(final EntityModel entityModel) {
final BreadcrumbModelProvider session = (BreadcrumbModelProvider) getSession();
final BreadcrumbModel breadcrumbModel = session.getBreadcrumbModel();
breadcrumbModel.visited(entityModel);
}
- private void removeAnyBreadcrumb(EntityModel entityModel) {
+ private void removeAnyBreadcrumb(final EntityModel entityModel) {
final BreadcrumbModelProvider session = (BreadcrumbModelProvider) getSession();
final BreadcrumbModel breadcrumbModel = session.getBreadcrumbModel();
breadcrumbModel.remove(entityModel);
@@ -172,6 +200,9 @@ public class EntityPage extends PageAbstract {
return IsisContext.getDeploymentType();
}
+ protected DeploymentCategory getDeploymentCategory() {
+ return getDeploymentType().getDeploymentCategory();
+ }
}
http://git-wip-us.apache.org/repos/asf/isis/blob/d1ed04ec/core/metamodel/src/main/java/org/apache/isis/core/runtime/authorization/standard/AuthorizationManagerStandard.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/runtime/authorization/standard/AuthorizationManagerStandard.java b/core/metamodel/src/main/java/org/apache/isis/core/runtime/authorization/standard/AuthorizationManagerStandard.java
index 836c7fa..d9d0f36 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/runtime/authorization/standard/AuthorizationManagerStandard.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/runtime/authorization/standard/AuthorizationManagerStandard.java
@@ -111,6 +111,12 @@ public class AuthorizationManagerStandard extends AuthorizationManagerAbstract i
if (isPerspectiveMember(identifier)) {
return true;
}
+
+ // no-op if is visibility context check at object-level
+ if (identifier.getMemberName().equals("")) {
+ return true;
+ }
+
if (authorizor.isVisibleInAnyRole(identifier)) {
return true;
}