ISIS-1359: enables autocomplete methods to be annotated as @Programmatic.

This is done by working directly with the Java reflection API, rather than 
through the Isis metamodel.

In addition:
- adds metamodel validation to ensure that the specified repository and method 
exist.
- updates documentation.


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/fbf5a459
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/fbf5a459
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/fbf5a459

Branch: refs/heads/master
Commit: fbf5a459da5dddebbe49bd33093ab120cfa6c2d5
Parents: f58e72e
Author: Dan Haywood <d...@haywood-associates.co.uk>
Authored: Thu Jun 23 15:00:04 2016 +0100
Committer: Dan Haywood <d...@haywood-associates.co.uk>
Committed: Thu Jun 23 15:00:04 2016 +0100

----------------------------------------------------------------------
 ...ant-DomainObject_autoCompleteRepository.adoc |  22 +++-
 .../autocomplete/AutoCompleteFacetAbstract.java | 116 ++++---------------
 .../DomainObjectAnnotationFacetFactory.java     | 100 ++++++++++++++--
 ...oCompleteFacetForAutoCompleteAnnotation.java |  32 +----
 ...oCompleteFacetForDomainObjectAnnotation.java |  38 ++----
 .../scalars/reference/ReferencePanel.java       |  29 +++--
 6 files changed, 163 insertions(+), 174 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/fbf5a459/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObject_autoCompleteRepository.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObject_autoCompleteRepository.adoc
 
b/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObject_autoCompleteRepository.adoc
index 54d035c..850d0c8 100644
--- 
a/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObject_autoCompleteRepository.adoc
+++ 
b/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObject_autoCompleteRepository.adoc
@@ -6,7 +6,8 @@
 
 
 
-The `autoCompleteRepository()` attribute nominates a single method on a domain 
service as the fallback means for lookuping up instances of the domain object 
using a simple string.
+The `autoCompleteRepository()` attribute nominates a single method on a domain 
service as the fallback means for
+looking up instances of the domain object using a simple string.
 
 For example, this might search for a customer by their name or number.  Or it 
could search for a country based on its ISO-3 code or user-friendly name.
 
@@ -68,11 +69,28 @@ where in this case `findByName` might be an existing action 
already defined:
 @DomainService(natureOfService=VIEW_MENU_ONLY)
 public class Customers {
     @Action(semantics=SemanticsOf.SAFE)
-    List<Customer> findByName(@ParameterLayout(named="name") String name);
+    public List<Customer> findByName(
+        @Parameter(minLength=3)             // <1>
+        @ParameterLayout(named="name")
+        String name);
     ...
 }
 ----
+<1> end-user must enter minimum number of characters to trigger the query
 
+(As of `1.13.0-SNAPSHOT`), the autocomplete action can also be a regular 
method, annotated using xref:rgant.adoc#_rgant_Programmatic[`@Programmatic`]:
+
+[source,java]
+----
+@DomainService(natureOfService=VIEW_MENU_ONLY)
+public class Customers {
+    @Programmatic
+    public List<Customer> findByName(
+        @Parameter(minLength=3)
+        String name);
+    ...
+}
+----
 
 
 [IMPORTANT]

http://git-wip-us.apache.org/repos/asf/isis/blob/fbf5a459/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/autocomplete/AutoCompleteFacetAbstract.java
----------------------------------------------------------------------
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/autocomplete/AutoCompleteFacetAbstract.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/autocomplete/AutoCompleteFacetAbstract.java
index dd0bfef..3e9bc47 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/autocomplete/AutoCompleteFacetAbstract.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/autocomplete/AutoCompleteFacetAbstract.java
@@ -19,6 +19,7 @@
 
 package org.apache.isis.core.metamodel.facets.object.autocomplete;
 
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.Collections;
 import java.util.List;
@@ -32,58 +33,40 @@ import 
org.apache.isis.core.metamodel.deployment.DeploymentCategory;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facetapi.FacetAbstract;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
-import org.apache.isis.core.metamodel.facets.ImperativeFacet;
-import 
org.apache.isis.core.metamodel.facets.actions.action.invocation.ActionInvocationFacet;
 import 
org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
 import org.apache.isis.core.metamodel.facets.param.autocomplete.MinLengthUtil;
 import org.apache.isis.core.metamodel.services.ServicesInjector;
 import 
org.apache.isis.core.metamodel.services.publishing.PublishingServiceInternal;
-import org.apache.isis.core.metamodel.spec.ActionType;
-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.ObjectAction;
-import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 
 public abstract class AutoCompleteFacetAbstract extends FacetAbstract 
implements AutoCompleteFacet {
 
-
     public static Class<? extends Facet> type() {
         return AutoCompleteFacet.class;
     }
 
-    private final Class<?> repositoryClass;
-    private final String actionName;
-
     private final DeploymentCategory deploymentCategory;
-    private final SpecificationLoader specificationLoader;
     private final AuthenticationSessionProvider authenticationSessionProvider;
     private final AdapterManager adapterManager;
     private final ServicesInjector servicesInjector;
+    private final Class<?> repositoryClass;
+    private final Method repositoryMethod;
 
     /**
      * lazily populated
      */
     private Integer minLength;
 
-    /**
-     * cached once searched for
-     */
-    private ObjectAction repositoryAction;
-    private boolean cachedRepositoryAction = false;
-    
-    private boolean cachedRepositoryObject = false;
-    private Object repository;
-
     public AutoCompleteFacetAbstract(
             final FacetHolder holder,
             final Class<?> repositoryClass,
-            final String actionName,
+            final Method repositoryMethod,
             final ServicesInjector servicesInjector) {
         super(type(), holder, Derivation.NOT_DERIVED);
+
         this.repositoryClass = repositoryClass;
-        this.actionName = actionName;
+        this.repositoryMethod = repositoryMethod;
+
         this.deploymentCategory = 
servicesInjector.getDeploymentCategoryProvider().getDeploymentCategory();
-        this.specificationLoader = servicesInjector.getSpecificationLoader();
         this.adapterManager = 
servicesInjector.getPersistenceSessionServiceInternal();
         this.servicesInjector = servicesInjector;
         this.authenticationSessionProvider = 
servicesInjector.getAuthenticationSessionProvider();
@@ -94,20 +77,20 @@ public abstract class AutoCompleteFacetAbstract extends 
FacetAbstract implements
             final String search,
             final InteractionInitiatedBy interactionInitiatedBy) {
 
-        cacheRepositoryAndRepositoryActionIfRequired();
-        if(repositoryAction == null || repository == null) {
-            return Collections.emptyList();
-        }
-        
-        final ObjectAdapter repositoryAdapter = 
adapterManager.getAdapterFor(repository);
-        final ObjectAdapter searchAdapter = adapterManager.adapterFor(search);
-
         final ObjectAdapter resultAdapter =
                 getPublishingServiceInternal().withPublishingSuppressed(new 
PublishingServiceInternal.Block<ObjectAdapter>() {
             @Override
             public ObjectAdapter exec() {
-                return repositoryAction.execute(repositoryAdapter, null, new 
ObjectAdapter[] { searchAdapter},
-                        interactionInitiatedBy);
+                final Object list = invoke();
+                return adapterManager.adapterFor(list);
+            }
+
+            private Object invoke()  {
+                try {
+                    return repositoryMethod.invoke(getRepository(), search);
+                } catch (IllegalAccessException | InvocationTargetException e) 
{
+                    return Collections.emptyList();
+                }
             }
         });
 
@@ -119,8 +102,11 @@ public abstract class AutoCompleteFacetAbstract extends 
FacetAbstract implements
         final CollectionFacet facet = 
CollectionFacet.Utils.getCollectionFacetFromSpec(resultAdapter);
         final Iterable<ObjectAdapter> adapterList = 
facet.iterable(resultAdapter);
 
-        return ObjectAdapter.Util.visibleAdapters(
-                        adapterList, interactionInitiatedBy);
+        return ObjectAdapter.Util.visibleAdapters(adapterList, 
interactionInitiatedBy);
+    }
+
+    private Object getRepository() {
+        return servicesInjector.lookupService(repositoryClass);
     }
 
     private PublishingServiceInternal getPublishingServiceInternal() {
@@ -128,70 +114,14 @@ public abstract class AutoCompleteFacetAbstract extends 
FacetAbstract implements
     }
 
 
-    private void cacheRepositoryAndRepositoryActionIfRequired() {
-        if(!cachedRepositoryAction) {
-            cacheRepositoryAction();
-        }
-        if(!cachedRepositoryObject) {
-            cacheRepositoryObject();
-        }
-    }
-
     @Override
     public int getMinLength() {
         if(minLength == null) {
-            final Method method = findMethod();
-            minLength = MinLengthUtil.determineMinLength(method);
+            minLength = MinLengthUtil.determineMinLength(repositoryMethod);
         }
         return minLength;
     }
 
-    private Method findMethod() {
-        if(!cachedRepositoryAction) {
-            cacheRepositoryAction();
-        }
-
-        final ActionInvocationFacet invocationFacet = 
repositoryAction.getFacet(ActionInvocationFacet.class);
-        if(invocationFacet instanceof ImperativeFacet) {
-            return findMethod((ImperativeFacet) invocationFacet);
-        }
-        final Facet underlyingFacet = invocationFacet.getUnderlyingFacet();
-        if(underlyingFacet instanceof ImperativeFacet) {
-            return findMethod((ImperativeFacet) underlyingFacet);
-        }
-        return null;
-    }
-
-    private Method findMethod(final ImperativeFacet invocationFacet) {
-        final ImperativeFacet facet = invocationFacet;
-        final List<Method> methods = facet.getMethods();
-        for (Method method : methods) {
-            final ImperativeFacet.Intent intent = facet.getIntent(method);
-            if(intent == ImperativeFacet.Intent.EXECUTE) {
-                return method;
-            }
-        }
-        return null;
-    }
-
-    private void cacheRepositoryAction() {
-        try {
-            final ObjectSpecification repositorySpec = 
specificationLoader.loadSpecification(repositoryClass);
-            final List<ObjectAction> objectActions =
-                    repositorySpec.getObjectActions(
-                            ActionType.USER, Contributed.EXCLUDED, 
ObjectAction.Filters.withId(actionName));
-
-            repositoryAction = objectActions.size() == 1? 
objectActions.get(0): null;
-        } finally {
-            cachedRepositoryAction = true;
-        }
-    }
-
-    private void cacheRepositoryObject() {
-        repository = servicesInjector.lookupService(repositoryClass);
-        cachedRepositoryObject = true;
-    }
-
     protected DeploymentCategory getDeploymentCategory() {
         return deploymentCategory;
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/fbf5a459/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
----------------------------------------------------------------------
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
index 9ff076e..d35a85a 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
@@ -53,6 +53,7 @@ import 
org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
 import org.apache.isis.core.metamodel.facets.MethodFinderUtils;
 import org.apache.isis.core.metamodel.facets.PostConstructMethodCache;
 import org.apache.isis.core.metamodel.facets.object.audit.AuditableFacet;
+import 
org.apache.isis.core.metamodel.facets.object.autocomplete.AutoCompleteFacet;
 import 
org.apache.isis.core.metamodel.facets.object.callbacks.CreatedLifecycleEventFacetForDomainObjectAnnotation;
 import 
org.apache.isis.core.metamodel.facets.object.callbacks.LoadedLifecycleEventFacetForDomainObjectAnnotation;
 import 
org.apache.isis.core.metamodel.facets.object.callbacks.PersistedLifecycleEventFacetForDomainObjectAnnotation;
@@ -85,6 +86,7 @@ import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import 
org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorComposite;
 import 
org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorForDeprecatedAnnotation;
+import 
org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorForValidationFailures;
 import 
org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorVisiting;
 import org.apache.isis.core.metamodel.specloader.validator.ValidationFailures;
 import org.apache.isis.core.metamodel.util.EventUtil;
@@ -100,6 +102,7 @@ public class DomainObjectAnnotationFacetFactory extends 
FacetFactoryAbstract
     private final MetaModelValidatorForDeprecatedAnnotation boundedValidator = 
new MetaModelValidatorForDeprecatedAnnotation(Bounded.class);
     private final MetaModelValidatorForDeprecatedAnnotation immutableValidator 
= new MetaModelValidatorForDeprecatedAnnotation(Immutable.class);
     private final MetaModelValidatorForDeprecatedAnnotation 
objectTypeValidator = new 
MetaModelValidatorForDeprecatedAnnotation(ObjectType.class);
+    private final MetaModelValidatorForValidationFailures autoCompleteInvalid 
= new MetaModelValidatorForValidationFailures();
 
 
 
@@ -189,28 +192,103 @@ public class DomainObjectAnnotationFacetFactory extends 
FacetFactoryAbstract
 
     void processAutoComplete(final ProcessClassContext processClassContext) {
         final Class<?> cls = processClassContext.getCls();
-        final DomainObject domainObject = Annotations.getAnnotation(cls, 
DomainObject.class);
         final FacetHolder facetHolder = processClassContext.getFacetHolder();
 
         // check for the deprecated @AutoComplete annotation first
-        final AutoComplete annotation = 
Annotations.getAnnotation(processClassContext.getCls(), AutoComplete.class);
-        Facet facet = autoCompleteValidator.flagIfPresent(
-                AutoCompleteFacetForAutoCompleteAnnotation.create(annotation, 
facetHolder,
-                        servicesInjector
-                ));
+        final AutoComplete autoCompleteAnnot = Annotations.getAnnotation(cls, 
AutoComplete.class);
+        Facet facet = 
autoCompleteValidator.flagIfPresent(createFor(facetHolder, autoCompleteAnnot, 
cls));
 
         // else check from @DomainObject(auditing=...)
         if(facet == null) {
-            facet = AutoCompleteFacetForDomainObjectAnnotation.create(
-                    domainObject, facetHolder,
-                    servicesInjector
-            );
+            final DomainObject domainObjectAnnot = 
Annotations.getAnnotation(cls, DomainObject.class);
+            facet = createFor(domainObjectAnnot, facetHolder, cls);
         }
 
         // then add
         FacetUtil.addFacet(facet);
     }
 
+    private AutoCompleteFacet createFor(
+            final FacetHolder facetHolder,
+            final AutoComplete annotation,
+            final Class<?> cls) {
+        if(annotation == null) {
+            return null;
+        }
+
+        final Class<?> repositoryClass = annotation.repository();
+        final String actionName = annotation.action();
+
+        if(!isServiceType(cls, "@AutoComplete", repositoryClass)) {
+            return null;
+        }
+        final Method repositoryMethod = findRepositoryMethod(cls, 
"@AutoComplete", repositoryClass, actionName);
+        if(repositoryMethod == null) {
+            return null;
+        }
+        return new AutoCompleteFacetForAutoCompleteAnnotation(
+                        facetHolder, repositoryClass, repositoryMethod, 
servicesInjector);
+    }
+
+    private AutoCompleteFacet createFor(
+            final DomainObject domainObject,
+            final FacetHolder facetHolder,
+            final Class<?> cls) {
+        if(domainObject == null) {
+            return null;
+        }
+
+        final Class<?> repositoryClass = domainObject.autoCompleteRepository();
+        if(repositoryClass == null || repositoryClass == Object.class) {
+            return null;
+        }
+        final String actionName = domainObject.autoCompleteAction();
+
+        if(!isServiceType(cls, "@DomainObject", repositoryClass)) {
+            return null;
+        }
+        final Method repositoryMethod = findRepositoryMethod(cls, 
"@DomainObject", repositoryClass, actionName);
+        if(repositoryMethod == null) {
+            return null;
+        }
+
+        return new AutoCompleteFacetForDomainObjectAnnotation(
+                        facetHolder, repositoryClass, repositoryMethod, 
servicesInjector);
+    }
+
+    private boolean isServiceType(
+            final Class<?> cls,
+            final String annotationName,
+            final Class<?> repositoryClass) {
+        final boolean isRegistered = 
servicesInjector.isRegisteredService(repositoryClass);
+        if(!isRegistered) {
+            autoCompleteInvalid.addFailure(
+                    "%s annotation on %s specifies unknown repository '%s'",
+                    annotationName, cls.getName(), repositoryClass.getName());
+        }
+        return isRegistered;
+    }
+
+    private Method findRepositoryMethod(
+            final Class<?> cls,
+            final String annotationName,
+            final Class<?> repositoryClass,
+            final String methodName) {
+        final Method[] methods = repositoryClass.getMethods();
+        for (Method method : methods) {
+            if(method.getName().equals(methodName)) {
+                final Class<?>[] parameterTypes = method.getParameterTypes();
+                if(parameterTypes.length == 1 && 
parameterTypes[0].equals(String.class)) {
+                    return method;
+                }
+            }
+        }
+        autoCompleteInvalid.addFailure(
+                "%s annotation on %s specifies action '%s' that does not exist 
in repository '%s'",
+                annotationName, cls.getName(), methodName, 
repositoryClass.getName());
+        return null;
+    }
+
     void processBounded(final ProcessClassContext processClassContext) {
         final Class<?> cls = processClassContext.getCls();
         final DomainObject domainObject = Annotations.getAnnotation(cls, 
DomainObject.class);
@@ -476,6 +554,8 @@ public class DomainObjectAnnotationFacetFactory extends 
FacetFactoryAbstract
         metaModelValidator.add(boundedValidator);
         metaModelValidator.add(immutableValidator);
         metaModelValidator.add(objectTypeValidator);
+
+        metaModelValidator.add(autoCompleteInvalid);
     }
 
     // //////////////////////////////////////

http://git-wip-us.apache.org/repos/asf/isis/blob/fbf5a459/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/autocomplete/AutoCompleteFacetForAutoCompleteAnnotation.java
----------------------------------------------------------------------
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/autocomplete/AutoCompleteFacetForAutoCompleteAnnotation.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/autocomplete/AutoCompleteFacetForAutoCompleteAnnotation.java
index df7b64a..fc9371d 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/autocomplete/AutoCompleteFacetForAutoCompleteAnnotation.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/autocomplete/AutoCompleteFacetForAutoCompleteAnnotation.java
@@ -19,14 +19,12 @@
 
 package org.apache.isis.core.metamodel.facets.object.domainobject.autocomplete;
 
-import org.apache.isis.applib.annotation.AutoComplete;
-import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
-import org.apache.isis.core.metamodel.deployment.DeploymentCategory;
+import java.lang.reflect.Method;
+
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
-import 
org.apache.isis.core.metamodel.facets.object.autocomplete.AutoCompleteFacet;
 import 
org.apache.isis.core.metamodel.facets.object.autocomplete.AutoCompleteFacetAbstract;
 import org.apache.isis.core.metamodel.services.ServicesInjector;
-import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 
 /**
  * @deprecated
@@ -34,30 +32,12 @@ import 
org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 @Deprecated
 public class AutoCompleteFacetForAutoCompleteAnnotation extends 
AutoCompleteFacetAbstract {
 
-    public static AutoCompleteFacet create(
-            final AutoComplete annotation,
-            final FacetHolder holder,
-            final ServicesInjector servicesInjector) {
-
-        if(annotation == null) {
-            return null;
-        }
-
-        final Class<?> repositoryClass = annotation.repository();
-        final String actionName = annotation.action();
-
-        return new AutoCompleteFacetForAutoCompleteAnnotation(holder, 
repositoryClass, actionName,
-                servicesInjector
-        );
-    }
-
-    private AutoCompleteFacetForAutoCompleteAnnotation(
+    public AutoCompleteFacetForAutoCompleteAnnotation(
             final FacetHolder holder,
             final Class<?> repositoryClass,
-            final String actionName,
+            final Method actionName,
             final ServicesInjector servicesInjector) {
-        super(holder, repositoryClass, actionName, servicesInjector
-        );
+        super(holder, repositoryClass, actionName, servicesInjector);
     }
 
 

http://git-wip-us.apache.org/repos/asf/isis/blob/fbf5a459/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/autocomplete/AutoCompleteFacetForDomainObjectAnnotation.java
----------------------------------------------------------------------
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/autocomplete/AutoCompleteFacetForDomainObjectAnnotation.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/autocomplete/AutoCompleteFacetForDomainObjectAnnotation.java
index 7c52c11..2478300 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/autocomplete/AutoCompleteFacetForDomainObjectAnnotation.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/autocomplete/AutoCompleteFacetForDomainObjectAnnotation.java
@@ -19,51 +19,27 @@
 
 package org.apache.isis.core.metamodel.facets.object.domainobject.autocomplete;
 
-import org.apache.isis.applib.annotation.DomainObject;
-import 
org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
-import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
-import org.apache.isis.core.metamodel.deployment.DeploymentCategory;
+import java.lang.reflect.Method;
+
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
-import 
org.apache.isis.core.metamodel.facets.object.autocomplete.AutoCompleteFacet;
 import 
org.apache.isis.core.metamodel.facets.object.autocomplete.AutoCompleteFacetAbstract;
 import org.apache.isis.core.metamodel.services.ServicesInjector;
-import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 
 public class AutoCompleteFacetForDomainObjectAnnotation extends 
AutoCompleteFacetAbstract {
 
     private final Class<?> repositoryClass;
     private final String actionName;
 
-    public static AutoCompleteFacet create(
-            final DomainObject domainObject,
-            final FacetHolder holder,
-            final ServicesInjector servicesInjector) {
-
-        if(domainObject == null) {
-            return null;
-        }
-
-        final Class<?> autoCompleteRepository = 
domainObject.autoCompleteRepository();
-        if(autoCompleteRepository == null || autoCompleteRepository == 
Object.class) {
-            return null;
-        }
-        final String autoCompleteAction = domainObject.autoCompleteAction();
-        return new AutoCompleteFacetForDomainObjectAnnotation(holder, 
autoCompleteRepository, autoCompleteAction, servicesInjector
-        );
-    }
-
-    private AutoCompleteFacetForDomainObjectAnnotation(
-            final FacetHolder holder,
+    public AutoCompleteFacetForDomainObjectAnnotation(
+            final FacetHolder facetHolder,
             final Class<?> repositoryClass,
-            final String actionName,
+            final Method repositoryMethod,
             final ServicesInjector servicesInjector) {
-        super(holder, repositoryClass, actionName, servicesInjector
-        );
+        super(facetHolder, repositoryClass, repositoryMethod, 
servicesInjector);
         this.repositoryClass = repositoryClass;
-        this.actionName = actionName;
+        this.actionName = repositoryMethod.getName();
     }
 
-
     /**
      * Introduced for testing only.
      */

http://git-wip-us.apache.org/repos/asf/isis/blob/fbf5a459/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
----------------------------------------------------------------------
diff --git 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
index 0d65bc8..0039bf6 100644
--- 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
+++ 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
@@ -265,20 +265,30 @@ public class ReferencePanel extends ScalarPanelAbstract {
                 entityLink.setRequired(getModel().isRequired());
                 select2Field = 
Select2ChoiceUtil.newSelect2Choice(ID_AUTO_COMPLETE, model, getModel());
                 setProviderAndCurrAndPending(select2Field, 
getModel().getActionArgsHint());
-                if(!getModel().hasChoices()) {
-                    final Settings settings = select2Field.getSettings();
+
+                final Settings settings = select2Field.getSettings();
+
+                // one of these three case should be true
+                // (as per the isEditableWithEitherAutoCompleteOrChoices() 
guard above)
+                if(getModel().hasChoices()) {
+
+                    settings.setPlaceholder(getModel().getName());
+
+                } else if(getModel().hasAutoComplete()) {
+
                     final int minLength = 
getModel().getAutoCompleteMinLength();
                     settings.setMinimumInputLength(minLength);
                     settings.setPlaceholder(getModel().getName());
-                }
-                if(hasObjectAutoComplete()) {
+
+                } else if(hasObjectAutoComplete()) {
                     final ObjectSpecification typeOfSpecification = 
getModel().getTypeOfSpecification();
                     final AutoCompleteFacet autoCompleteFacet = 
typeOfSpecification.getFacet(AutoCompleteFacet.class);
-                    final Settings settings = select2Field.getSettings();
                     final int minLength = autoCompleteFacet.getMinLength();
                     settings.setMinimumInputLength(minLength);
                 }
+
                 entityLink.addOrReplace(select2Field);
+
             } else {
                 //
                 // the select2Field already exists, so the widget has been 
rendered before.  If it is
@@ -340,7 +350,7 @@ public class ReferencePanel extends ScalarPanelAbstract {
             
             resetIfCurrentNotInChoices(select2Field, choiceMementos);
             
-        } else if(hasParamOrPropertyAutoComplete()) {
+        } else if(getModel().hasAutoComplete()) {
             select2Field.setProvider(providerForParamOrPropertyAutoComplete());
             getModel().clearPending();
         } else {
@@ -508,12 +518,7 @@ public class ReferencePanel extends ScalarPanelAbstract {
         if(getModel().isViewMode()) {
             return false;
         }
-        return getModel().hasChoices() || hasParamOrPropertyAutoComplete() || 
hasObjectAutoComplete();
-    }
-
-    // called by isEditableWithEitherAutoCompleteOrChoices, also 
syncProviderAndCurrAndPending
-    private boolean hasParamOrPropertyAutoComplete() {
-        return getModel().hasAutoComplete();
+        return getModel().hasChoices() || getModel().hasAutoComplete() || 
hasObjectAutoComplete();
     }
 
     // called by isEditableWithEitherAutoCompleteOrChoices

Reply via email to