You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2018/09/11 20:21:48 UTC

[isis] 05/06: ISIS-1976: fixes improper OA lookup

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch ISIS-1976-rethink-object-adapters
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 0f2621ab6f30e12e04aed294f6ee787bb8ad17dc
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Sep 11 20:47:20 2018 +0200

    ISIS-1976: fixes improper OA lookup
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1976
---
 .../commons/lang/MethodInvocationPreprocessor.java | 31 ++++++++-
 .../PersistenceSessionServiceInternalDefault.java  |  3 +-
 .../adaptermanager/ObjectAdapterContext.java       |  9 +--
 .../ObjectAdapterContext_AdapterManager.java       | 76 ----------------------
 ...ctAdapterContext_ObjectAdapterByIdProvider.java | 10 +--
 ...ObjectAdapterContext_ObjectAdapterProvider.java |  1 +
 .../persistence/adaptermanager/OidProviders.java   | 18 +++++
 7 files changed, 59 insertions(+), 89 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/MethodInvocationPreprocessor.java b/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/MethodInvocationPreprocessor.java
index 2a54e76..eedd954 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/MethodInvocationPreprocessor.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/MethodInvocationPreprocessor.java
@@ -19,6 +19,8 @@
 
 package org.apache.isis.core.commons.lang;
 
+import static org.apache.isis.commons.internal.base._NullSafe.isEmpty;
+
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.Collection;
@@ -27,7 +29,6 @@ import java.util.Set;
 import java.util.SortedSet;
 
 import org.apache.isis.commons.internal.base._Casts;
-import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.commons.internal.collections._Arrays;
 import org.apache.isis.commons.internal.collections._Collections;
 
@@ -46,7 +47,7 @@ public class MethodInvocationPreprocessor {
     public static Object invoke(Method method, Object targetPojo, Object[] executionParameters)
             throws IllegalAccessException, InvocationTargetException {
 
-        if (_NullSafe.isEmpty(executionParameters)) {
+        if (isEmpty(executionParameters)) {
             return method.invoke(targetPojo, executionParameters);
         }
 
@@ -60,11 +61,16 @@ public class MethodInvocationPreprocessor {
             ++i;
         }
 
-        return method.invoke(targetPojo, adaptedExecutionParameters);
+        try {
+            return method.invoke(targetPojo, adaptedExecutionParameters);
+        } catch (IllegalArgumentException e) {
+            throw verboseArgumentException(parameterTypes, adaptedExecutionParameters, e);
+        }
     }
 
     // -- OBJECT ADAPTER
 
+
     /**
      * Replaces obj (if required) to be conform with the parameterType
      * @param obj
@@ -110,5 +116,24 @@ public class MethodInvocationPreprocessor {
         return obj;
     }
 
+    private static IllegalArgumentException verboseArgumentException(
+            Class<?>[] parameterTypes, 
+            Object[] adaptedExecutionParameters,
+            IllegalArgumentException e) {
+        
+        final StringBuilder sb = new StringBuilder();
+        
+        for(int j=0;j<parameterTypes.length;++j) {
+            final Class<?> parameterType = parameterTypes[j];
+            final Object parameterValue = adaptedExecutionParameters[j];
+        
+            sb.append(String.format("expected-param-type[%d]: %s, got %s\n", 
+                    j, parameterType.getName(), parameterValue.getClass().getName()));
+        }
+        
+        // re-throw more verbose
+        return new IllegalArgumentException(sb.toString(), e);
+    }
 
+    
 }
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/persistsession/PersistenceSessionServiceInternalDefault.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/persistsession/PersistenceSessionServiceInternalDefault.java
index 901bb95..5b583c9 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/persistsession/PersistenceSessionServiceInternalDefault.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/persistsession/PersistenceSessionServiceInternalDefault.java
@@ -38,6 +38,7 @@ import org.apache.isis.applib.services.xactn.TransactionState;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapterProvider;
+import org.apache.isis.core.metamodel.adapter.concurrency.ConcurrencyChecking;
 import org.apache.isis.core.metamodel.adapter.oid.Oid;
 import org.apache.isis.core.metamodel.adapter.oid.RootOid;
 import org.apache.isis.core.metamodel.services.persistsession.PersistenceSessionServiceInternal;
@@ -96,7 +97,7 @@ public class PersistenceSessionServiceInternalDefault implements PersistenceSess
             return ps.fetchPersistentPojoInTransaction(oid);
         } else {
             
-            final ObjectAdapter adapter = adapterFor(oid);
+            final ObjectAdapter adapter = getPersistenceSession().adapterFor(oid, ConcurrencyChecking.NO_CHECK);
             if(adapter == null) {
                 return null;
             }            
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext.java
index a914314..9a2bd69 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext.java
@@ -70,7 +70,6 @@ final public class ObjectAdapterContext {
     private final PersistenceSession persistenceSession; 
     private final SpecificationLoader specificationLoader;
     private final ObjectAdapterContext_ObjectAdapterProvider objectAdapterProviderMixin;
-    private final ObjectAdapterContext_AdapterManager adapterManagerMixin;
     private final ObjectAdapterContext_MementoSupport mementoSupportMixin;
     private final ObjectAdapterContext_ServiceLookup serviceLookupMixin;
     private final ObjectAdapterContext_NewIdentifier newIdentifierMixin;
@@ -87,7 +86,6 @@ final public class ObjectAdapterContext {
             PersistenceSession persistenceSession) {
 
         this.objectAdapterProviderMixin = new ObjectAdapterContext_ObjectAdapterProvider(this, persistenceSession);
-        this.adapterManagerMixin = new ObjectAdapterContext_AdapterManager(this, persistenceSession);
         this.mementoSupportMixin = new ObjectAdapterContext_MementoSupport(this, persistenceSession);
         this.serviceLookupMixin = new ObjectAdapterContext_ServiceLookup(this, servicesInjector);
         this.newIdentifierMixin = new ObjectAdapterContext_NewIdentifier(this, persistenceSession);
@@ -209,6 +207,9 @@ final public class ObjectAdapterContext {
     @Deprecated
     public ObjectAdapter injectServices(final ObjectAdapter adapter) {
         Objects.requireNonNull(adapter);
+        if(adapter.isValue()) {
+            return adapter; // guard against value objects
+        }
         final Object pojo = adapter.getObject();
         servicesInjector.injectServicesInto(pojo);
         return adapter;
@@ -259,7 +260,7 @@ final public class ObjectAdapterContext {
                 specificationLoader.loadSpecification(viewModelPojo.getClass());
         final ObjectSpecId objectSpecId = objectSpecification.getSpecId();
         final RootOid newRootOid = RootOid.create(objectSpecId, UUID.randomUUID().toString());
-        final ObjectAdapter createdAdapter = adapterManagerMixin.createRootOrAggregatedAdapter(newRootOid, viewModelPojo);
+        final ObjectAdapter createdAdapter = createRootOrAggregatedAdapter(newRootOid, viewModelPojo);
         return createdAdapter;
     }
 
@@ -270,7 +271,7 @@ final public class ObjectAdapterContext {
         final ObjectSpecId objectSpecId = objectSpecification.getSpecId();
         final RootOid newRootOid = rootOidFactory.apply(objectSpecId);
 
-        final ObjectAdapter viewModelAdapter = adapterManagerMixin.recreatePojo(newRootOid, viewModelPojo);
+        final ObjectAdapter viewModelAdapter = recreatePojo(newRootOid, viewModelPojo);
         return viewModelAdapter;
     }
 
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_AdapterManager.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_AdapterManager.java
deleted file mode 100644
index a433e1b..0000000
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_AdapterManager.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.core.runtime.system.persistence.adaptermanager;
-
-import java.util.Objects;
-
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.adapter.oid.Oid;
-import org.apache.isis.core.metamodel.adapter.oid.ParentedCollectionOid;
-import org.apache.isis.core.metamodel.adapter.oid.RootOid;
-import org.apache.isis.core.metamodel.services.ServicesInjector;
-import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
-
-/**
- * package private mixin for ObjectAdapterContext
- * <p>
- * Responsibility: AdapterManager 'legacy' support
- * </p>
- *  
- * @since 2.0.0-M2
- */
-class ObjectAdapterContext_AdapterManager {
-    
-    private final ObjectAdapterContext objectAdapterContext;
-    @SuppressWarnings("unused")
-    private final PersistenceSession persistenceSession;
-    private final ServicesInjector servicesInjector; 
-    
-    ObjectAdapterContext_AdapterManager(ObjectAdapterContext objectAdapterContext,
-            PersistenceSession persistenceSession) {
-        this.objectAdapterContext = objectAdapterContext;
-        this.persistenceSession = persistenceSession;
-        this.servicesInjector = persistenceSession.getServicesInjector();
-    }
-    
-    ObjectAdapter recreatePojo(Oid oid, Object recreatedPojo) {
-        final ObjectAdapter createdAdapter = createRootOrAggregatedAdapter(oid, recreatedPojo);
-        return injectServices(createdAdapter);
-    }
-
-    ObjectAdapter injectServices(final ObjectAdapter adapter) {
-        Objects.requireNonNull(adapter);
-        final Object pojo = adapter.getObject();
-        servicesInjector.injectServicesInto(pojo);
-        return adapter;
-    }
-    
-    ObjectAdapter createRootOrAggregatedAdapter(final Oid oid, final Object pojo) {
-        final ObjectAdapter createdAdapter;
-        if(oid instanceof RootOid) {
-            final RootOid rootOid = (RootOid) oid;
-            createdAdapter = objectAdapterContext.getFactories().createRootAdapter(pojo, rootOid);
-        } else /*if (oid instanceof CollectionOid)*/ {
-            final ParentedCollectionOid collectionOid = (ParentedCollectionOid) oid;
-            createdAdapter = objectAdapterContext.getFactories().createCollectionAdapter(pojo, collectionOid);
-        }
-        return createdAdapter;
-    }
-    
-}
\ No newline at end of file
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterByIdProvider.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterByIdProvider.java
index 8051e09..96e4ce8 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterByIdProvider.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterByIdProvider.java
@@ -29,6 +29,7 @@ import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.commons.internal.collections._Maps;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.commons.ensure.Ensure;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapterByIdProvider;
 import org.apache.isis.core.metamodel.adapter.concurrency.ConcurrencyChecking;
@@ -128,7 +129,7 @@ class ObjectAdapterContext_ObjectAdapterByIdProvider implements ObjectAdapterByI
         //FIXME[ISIS-1976] remove guard
         final ObjectAdapter serviceAdapter = objectAdapterContext.lookupServiceAdapterFor(rootOid);
         if (serviceAdapter != null) {
-            _Exceptions.unexpectedCodeReach();
+            //throw _Exceptions.unexpectedCodeReach();
             return serviceAdapter;
         }
         
@@ -214,16 +215,15 @@ class ObjectAdapterContext_ObjectAdapterByIdProvider implements ObjectAdapterByI
         final ObjectSpecification spec =
                 specificationLoader.lookupBySpecId(rootOid.getObjectSpecId());
         final Object pojo;
-
         if(rootOid.isViewModel()) {
-
             final String memento = rootOid.getIdentifier();
             pojo = recreateViewModel(spec, memento);
-
         } else {
             pojo = objectAdapterContext.instantiateAndInjectServices(spec);
-
         }
+        
+        Ensure.ensure("unlikely", !(pojo instanceof Oid));
+        
         return pojo;
     }
     
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
index 7c5f20f..8e722da 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
@@ -65,6 +65,7 @@ class ObjectAdapterContext_ObjectAdapterProvider implements ObjectAdapterProvide
         this.specificationLoader = servicesInjector.getSpecificationLoader();
         
         this.oidFactory = OidFactory.builder(pojo->specificationLoader.loadSpecification(pojo.getClass()))
+                .add(new OidProviders.GuardAgainstRootOid())
                 .add(new OidProviders.OidForServices())
                 .add(new OidProviders.OidForValues())
                 .add(new OidProviders.OidForViewModels())
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/OidProviders.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/OidProviders.java
index 58eef68..491e836 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/OidProviders.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/OidProviders.java
@@ -32,6 +32,24 @@ import org.apache.isis.core.runtime.system.persistence.adaptermanager.factories.
 
 public class OidProviders {
 
+    
+    public static class GuardAgainstRootOid implements OidProvider {
+
+        @Override
+        public boolean isHandling(Object pojo, ObjectSpecification spec) {
+            return pojo instanceof RootOid;
+        }
+
+        @Override
+        public RootOid oidFor(Object pojo, ObjectSpecification spec) {
+            throw new IllegalArgumentException("Cannot create a RootOid for pojo, "
+                    + "when pojo is instance of RootOid. You might want to ask "
+                    + "ObjectAdapterByIdProvider for an ObjectAdapter instead.");
+        }
+
+    }
+    
+    
     public static class OidForServices implements OidProvider {
 
         @Override