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 2013/06/10 17:46:51 UTC

git commit: ISIS-434: autocomplete for properties

Updated Branches:
  refs/heads/master 9bda4c3f3 -> 8af98a50f


ISIS-434: autocomplete for properties


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

Branch: refs/heads/master
Commit: 8af98a50f093034e711b0c0f93a274b455fc7ef7
Parents: 9bda4c3
Author: Dan Haywood <da...@apache.org>
Authored: Mon Jun 10 16:46:02 2013 +0100
Committer: Dan Haywood <da...@apache.org>
Committed: Mon Jun 10 16:46:02 2013 +0100

----------------------------------------------------------------------
 .../entitylink/EntityLinkSelect2Panel.java      |  9 +-
 .../autocomplete/AutoCompleteFacetAbstract.java |  4 +-
 .../autocomplete/PropertyAutoCompleteFacet.java | 44 +++++++++
 .../specimpl/OneToOneAssociationImpl.java       | 18 +++-
 .../PropertyAutoCompleteFacetAbstract.java      | 40 ++++++++
 .../PropertyAutoCompleteFacetFactory.java       | 81 ++++++++++++++++
 .../PropertyAutoCompleteFacetViaMethod.java     | 98 ++++++++++++++++++++
 .../dflt/ProgrammingModelFacetsJava5.java       |  2 +
 .../PropertyMethodsFacetFactoryTest.java        | 32 +++++++
 .../dom/src/main/java/dom/todo/ToDoItem.java    |  1 +
 10 files changed, 319 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/8af98a50/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitylink/EntityLinkSelect2Panel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitylink/EntityLinkSelect2Panel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitylink/EntityLinkSelect2Panel.java
index 257cdd7..62c655b 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitylink/EntityLinkSelect2Panel.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitylink/EntityLinkSelect2Panel.java
@@ -20,6 +20,7 @@
 package org.apache.isis.viewer.wicket.ui.components.widgets.entitylink;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 
 import com.google.common.base.Function;
@@ -290,11 +291,11 @@ public class EntityLinkSelect2Panel extends FormComponentPanelAbstract<ObjectAda
                 final ScalarModel scalarModel = (ScalarModel) entityModel;
                 final boolean hasAutoComplete = scalarModel.hasAutoComplete();
                 if(!hasAutoComplete) {
-                    return null;
+                    return Collections.emptyList();
                 }
                 final List<ObjectAdapter> autoCompleteChoices = scalarModel.getAutoComplete(term);
                 if(autoCompleteChoices.isEmpty()) {
-                    return null;
+                    return Collections.emptyList();
                 }
                 // take a copy otherwise is only lazily evaluated
                 return Lists.newArrayList(Lists.transform(autoCompleteChoices, Mementos.fromAdapter()));
@@ -316,11 +317,11 @@ public class EntityLinkSelect2Panel extends FormComponentPanelAbstract<ObjectAda
                 final ScalarModel scalarModel = (ScalarModel) entityModel;
                 final boolean hasChoices = scalarModel.hasChoices();
                 if(!hasChoices) {
-                    return null;
+                    return Collections.emptyList();
                 }
                 final List<ObjectAdapter> choices = scalarModel.getChoices();
                 if(choices.isEmpty()) {
-                    return null;
+                    return Collections.emptyList();
                 }
                 // take a copy otherwise is only lazily evaluated
                 return Lists.newArrayList(Lists.transform(choices, Mementos.fromAdapter()));

http://git-wip-us.apache.org/repos/asf/isis/blob/8af98a50/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 cfd9641..d5e8fda 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
@@ -73,7 +73,7 @@ public abstract class AutoCompleteFacetAbstract extends FacetAbstract implements
 
         cacheRepositoryAndRepositoryActionIfRequired();
         if(repositoryAction == null || repository == null) {
-            return Collections.<ObjectAdapter>emptyList();
+            return Collections.emptyList();
         }
         
         final ObjectAdapter repositoryAdapter = adapterManager.getAdapterFor(repository);
@@ -81,7 +81,7 @@ public abstract class AutoCompleteFacetAbstract extends FacetAbstract implements
         final ObjectAdapter resultAdapter = repositoryAction.execute(repositoryAdapter, new ObjectAdapter[] { searchAdapter} );
         // check a collection was returned
         if(CollectionFacetUtils.getCollectionFacetFromSpec(resultAdapter) == null) {
-            return Collections.<ObjectAdapter>emptyList();
+            return Collections.emptyList();
         }
         return CollectionFacetUtils.convertToAdapterList(resultAdapter);
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/8af98a50/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/PropertyAutoCompleteFacet.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/PropertyAutoCompleteFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/PropertyAutoCompleteFacet.java
new file mode 100644
index 0000000..4fa376d
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/PropertyAutoCompleteFacet.java
@@ -0,0 +1,44 @@
+/*
+ *  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.metamodel.facets.properties.autocomplete;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.spec.SpecificationLoader;
+
+/**
+ * Provides a set of auto-complete choices for a property.
+ * 
+ * <p>
+ * Viewers would typically represent this as a drop-down list box for the
+ * property.
+ * 
+ * <p>
+ * In the standard Apache Isis Programming Model, corresponds to the
+ * <tt>autoCompletexx</tt> supporting method for the property with accessor
+ * <tt>getXxx</tt>.
+ */
+public interface PropertyAutoCompleteFacet extends Facet {
+
+    /**
+     * Gets the available auto-complete choices for this property.
+     */
+    public Object[] autoComplete(ObjectAdapter inObject, String searchArg);
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/8af98a50/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationImpl.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationImpl.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationImpl.java
index 5e29b0e..4b2885d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationImpl.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationImpl.java
@@ -37,6 +37,7 @@ import org.apache.isis.core.metamodel.facets.FacetedMethod;
 import org.apache.isis.core.metamodel.facets.accessor.PropertyOrCollectionAccessorFacet;
 import org.apache.isis.core.metamodel.facets.mandatory.MandatoryFacet;
 import org.apache.isis.core.metamodel.facets.object.bounded.BoundedFacetUtils;
+import org.apache.isis.core.metamodel.facets.properties.autocomplete.PropertyAutoCompleteFacet;
 import org.apache.isis.core.metamodel.facets.properties.choices.PropertyChoicesFacet;
 import org.apache.isis.core.metamodel.facets.properties.defaults.PropertyDefaultFacet;
 import org.apache.isis.core.metamodel.facets.properties.modify.PropertyClearFacet;
@@ -264,13 +265,22 @@ public class OneToOneAssociationImpl extends ObjectAssociationAbstract implement
     
     @Override
     public boolean hasAutoComplete() {
-        // TODO...
-        return false;
+        final PropertyAutoCompleteFacet propertyAutoCompleteFacet = getFacet(PropertyAutoCompleteFacet.class);
+        return propertyAutoCompleteFacet != null;
     }
 
     @Override
-    public ObjectAdapter[] getAutoComplete(ObjectAdapter object, String searchArg) {
-        return new ObjectAdapter[0];
+    public ObjectAdapter[] getAutoComplete(ObjectAdapter ownerAdapter, String searchArg) {
+        final PropertyAutoCompleteFacet propertyAutoCompleteFacet = getFacet(PropertyAutoCompleteFacet.class);
+        final Object[] pojoOptions = propertyAutoCompleteFacet.autoComplete(ownerAdapter, searchArg);
+        if (pojoOptions != null) {
+            final ObjectAdapter[] options = new ObjectAdapter[pojoOptions.length];
+            for (int i = 0; i < options.length; i++) {
+                options[i] = getAdapterManager().adapterFor(pojoOptions[i]);
+            }
+            return options;
+        }
+        return null;
     }
 
     // /////////////////////////////////////////////////////////////

http://git-wip-us.apache.org/repos/asf/isis/blob/8af98a50/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/properties/autocomplete/PropertyAutoCompleteFacetAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/properties/autocomplete/PropertyAutoCompleteFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/properties/autocomplete/PropertyAutoCompleteFacetAbstract.java
new file mode 100644
index 0000000..ddd9ddb
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/properties/autocomplete/PropertyAutoCompleteFacetAbstract.java
@@ -0,0 +1,40 @@
+/*
+ *  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.progmodel.facets.properties.autocomplete;
+
+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.properties.autocomplete.PropertyAutoCompleteFacet;
+import org.apache.isis.core.metamodel.facets.properties.choices.PropertyChoicesFacet;
+import org.apache.isis.core.metamodel.spec.SpecificationLoader;
+
+public abstract class PropertyAutoCompleteFacetAbstract extends FacetAbstract implements PropertyAutoCompleteFacet {
+
+    public static Class<? extends Facet> type() {
+        return PropertyAutoCompleteFacet.class;
+    }
+
+    public PropertyAutoCompleteFacetAbstract(final FacetHolder holder) {
+        super(type(), holder, Derivation.NOT_DERIVED);
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/8af98a50/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/properties/autocomplete/PropertyAutoCompleteFacetFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/properties/autocomplete/PropertyAutoCompleteFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/properties/autocomplete/PropertyAutoCompleteFacetFactory.java
new file mode 100644
index 0000000..2e2b595
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/properties/autocomplete/PropertyAutoCompleteFacetFactory.java
@@ -0,0 +1,81 @@
+/*
+ *  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.progmodel.facets.properties.autocomplete;
+
+import java.lang.reflect.Method;
+
+import org.apache.isis.core.commons.lang.NameUtils;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManagerAware;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facetapi.FeatureType;
+import org.apache.isis.core.metamodel.methodutils.MethodScope;
+import org.apache.isis.core.progmodel.facets.MethodFinderUtils;
+import org.apache.isis.core.progmodel.facets.MethodPrefixBasedFacetFactoryAbstract;
+import org.apache.isis.core.progmodel.facets.MethodPrefixConstants;
+
+public class PropertyAutoCompleteFacetFactory extends MethodPrefixBasedFacetFactoryAbstract implements AdapterManagerAware {
+
+    private static final String[] PREFIXES = { MethodPrefixConstants.AUTO_COMPLETE_PREFIX };
+
+    private AdapterManager adapterManager;
+
+    public PropertyAutoCompleteFacetFactory() {
+        super(FeatureType.PROPERTIES_ONLY, OrphanValidation.VALIDATE, PREFIXES);
+    }
+
+    @Override
+    public void process(final ProcessMethodContext processMethodContext) {
+
+        attachPropertyAutoCompleteFacetIfChoicesMethodIsFound(processMethodContext);
+    }
+
+    private void attachPropertyAutoCompleteFacetIfChoicesMethodIsFound(final ProcessMethodContext processMethodContext) {
+
+        final Method getMethod = processMethodContext.getMethod();
+        final String capitalizedName = NameUtils.javaBaseName(getMethod.getName());
+
+        final Class<?> cls = processMethodContext.getCls();
+        final Class<?> returnType = getMethod.getReturnType();
+        final Method autoCompleteMethod = MethodFinderUtils.findMethod(cls, MethodScope.OBJECT, MethodPrefixConstants.AUTO_COMPLETE_PREFIX + capitalizedName, null, new Class[]{String.class});
+        if (autoCompleteMethod == null) {
+            return;
+        }
+        processMethodContext.removeMethod(autoCompleteMethod);
+
+        final FacetHolder property = processMethodContext.getFacetHolder();
+        FacetUtil.addFacet(new PropertyAutoCompleteFacetViaMethod(autoCompleteMethod, returnType, property, getSpecificationLoader(), getAdapterManager()));
+    }
+
+    // ///////////////////////////////////////////////////////
+    // Dependencies (injected)
+    // ///////////////////////////////////////////////////////
+
+    @Override
+    public void setAdapterManager(final AdapterManager adapterManager) {
+        this.adapterManager = adapterManager;
+    }
+
+    protected AdapterManager getAdapterManager() {
+        return adapterManager;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/8af98a50/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/properties/autocomplete/PropertyAutoCompleteFacetViaMethod.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/properties/autocomplete/PropertyAutoCompleteFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/properties/autocomplete/PropertyAutoCompleteFacetViaMethod.java
new file mode 100644
index 0000000..470cb86
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/properties/autocomplete/PropertyAutoCompleteFacetViaMethod.java
@@ -0,0 +1,98 @@
+/*
+ *  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.progmodel.facets.properties.autocomplete;
+
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.isis.core.commons.lang.ArrayUtil;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.adapter.util.AdapterInvokeUtils;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.ImperativeFacet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.SpecificationLoader;
+import org.apache.isis.core.progmodel.facets.CollectionUtils;
+
+public class PropertyAutoCompleteFacetViaMethod extends PropertyAutoCompleteFacetAbstract implements ImperativeFacet {
+
+    private final Method method;
+    private final Class<?> choicesClass;
+
+    private final AdapterManager adapterManager;
+    private SpecificationLoader specificationLookup;
+
+    public PropertyAutoCompleteFacetViaMethod(final Method method, final Class<?> choicesClass, final FacetHolder holder, final SpecificationLoader specificationLookup, final AdapterManager adapterManager) {
+        super(holder);
+        this.method = method;
+        this.choicesClass = choicesClass;
+        this.specificationLookup = specificationLookup;
+        this.adapterManager = adapterManager;
+    }
+
+    /**
+     * Returns a singleton list of the {@link Method} provided in the
+     * constructor.
+     */
+    @Override
+    public List<Method> getMethods() {
+        return Collections.singletonList(method);
+    }
+
+    @Override
+    public boolean impliesResolve() {
+        return true;
+    }
+
+    @Override
+    public boolean impliesObjectChanged() {
+        return false;
+    }
+
+    @Override
+    public Object[] autoComplete(ObjectAdapter owningAdapter, String searchArg) {
+        final Object options = AdapterInvokeUtils.invoke(method, owningAdapter, searchArg);
+        if (options == null) {
+            return null;
+        }
+        if (options.getClass().isArray()) {
+            return ArrayUtil.getObjectAsObjectArray(options);
+        }
+        final ObjectSpecification specification = specificationLookup.loadSpecification(choicesClass);
+        return CollectionUtils.getCollectionAsObjectArray(options, specification, getAdapterManager());
+    }
+
+    @Override
+    protected String toStringValues() {
+        return "method=" + method + ",class=" + choicesClass;
+    }
+
+    // ////////////////////////////////////////////
+    // Dependencies
+    // ////////////////////////////////////////////
+
+    protected AdapterManager getAdapterManager() {
+        return adapterManager;
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/8af98a50/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java b/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
index d08ba52..7d56f17 100644
--- a/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
+++ b/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
@@ -145,6 +145,7 @@ import org.apache.isis.core.progmodel.facets.param.validate.maxlenannot.MaxLengt
 import org.apache.isis.core.progmodel.facets.param.validate.perspec.MustSatisfySpecificationOnParameterFacetFactory;
 import org.apache.isis.core.progmodel.facets.param.validate.regexannot.RegExFacetAnnotationForParameterFacetFactory;
 import org.apache.isis.core.progmodel.facets.properties.accessor.PropertyAccessorFacetFactory;
+import org.apache.isis.core.progmodel.facets.properties.autocomplete.PropertyAutoCompleteFacetFactory;
 import org.apache.isis.core.progmodel.facets.properties.choices.enums.PropertyChoicesFacetDerivedFromChoicesFacetFacetFactory;
 import org.apache.isis.core.progmodel.facets.properties.choices.method.PropertyChoicesFacetFactory;
 import org.apache.isis.core.progmodel.facets.properties.defaults.fromtype.PropertyDefaultDerivedFromTypeFacetFactory;
@@ -252,6 +253,7 @@ public final class ProgrammingModelFacetsJava5 extends ProgrammingModelAbstract
         
         addFactory(PropertyValidateFacetFactory.class);
         addFactory(PropertyChoicesFacetFactory.class);
+        addFactory(PropertyAutoCompleteFacetFactory.class);
         addFactory(PropertyDefaultFacetFactory.class);
         addFactory(PropertyOptionalFacetFactory.class);
 

http://git-wip-us.apache.org/repos/asf/isis/blob/8af98a50/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/properties/PropertyMethodsFacetFactoryTest.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/properties/PropertyMethodsFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/properties/PropertyMethodsFacetFactoryTest.java
index 823c79b..c40af70 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/properties/PropertyMethodsFacetFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/properties/PropertyMethodsFacetFactoryTest.java
@@ -29,6 +29,7 @@ import org.apache.isis.core.metamodel.facets.describedas.DescribedAsFacet;
 import org.apache.isis.core.metamodel.facets.hide.HiddenFacet;
 import org.apache.isis.core.metamodel.facets.named.NamedFacet;
 import org.apache.isis.core.metamodel.facets.notpersisted.NotPersistedFacet;
+import org.apache.isis.core.metamodel.facets.properties.autocomplete.PropertyAutoCompleteFacet;
 import org.apache.isis.core.metamodel.facets.properties.choices.PropertyChoicesFacet;
 import org.apache.isis.core.metamodel.facets.properties.defaults.PropertyDefaultFacet;
 import org.apache.isis.core.metamodel.facets.properties.modify.PropertyClearFacet;
@@ -58,6 +59,8 @@ import org.apache.isis.core.progmodel.facets.members.named.staticmethod.NamedFac
 import org.apache.isis.core.progmodel.facets.members.named.staticmethod.NamedFacetViaNameMethodFacetFactory;
 import org.apache.isis.core.progmodel.facets.properties.accessor.PropertyAccessorFacetFactory;
 import org.apache.isis.core.progmodel.facets.properties.accessor.PropertyAccessorFacetViaAccessor;
+import org.apache.isis.core.progmodel.facets.properties.autocomplete.PropertyAutoCompleteFacetFactory;
+import org.apache.isis.core.progmodel.facets.properties.autocomplete.PropertyAutoCompleteFacetViaMethod;
 import org.apache.isis.core.progmodel.facets.properties.choices.method.PropertyChoicesFacetFactory;
 import org.apache.isis.core.progmodel.facets.properties.choices.method.PropertyChoicesFacetViaMethod;
 import org.apache.isis.core.progmodel.facets.properties.defaults.method.PropertyDefaultFacetFactory;
@@ -361,6 +364,35 @@ public class PropertyMethodsFacetFactoryTest extends AbstractFacetFactoryTest {
 
         assertTrue(methodRemover.getRemovedMethodMethodCalls().contains(propertyChoicesMethod));
     }
+    
+    public void testAutoCompleteFacetFoundAndMethodRemoved() {
+        final PropertyAutoCompleteFacetFactory facetFactory = new PropertyAutoCompleteFacetFactory();
+        facetFactory.setSpecificationLookup(reflector);
+        
+        class Customer {
+            @SuppressWarnings("unused")
+            public String getFirstName() {
+                return null;
+            }
+            
+            @SuppressWarnings("unused")
+            public Object[] autoCompleteFirstName(String searchArg) {
+                return null;
+            }
+        }
+        final Method propertyAccessorMethod = findMethod(Customer.class, "getFirstName");
+        final Method propertyAutoCompleteMethod = findMethod(Customer.class, "autoCompleteFirstName", new Class[]{String.class});
+        
+        facetFactory.process(new ProcessMethodContext(Customer.class, propertyAccessorMethod, methodRemover, facetedMethod));
+        
+        final Facet facet = facetedMethod.getFacet(PropertyAutoCompleteFacet.class);
+        assertNotNull(facet);
+        assertTrue(facet instanceof PropertyAutoCompleteFacetViaMethod);
+        final PropertyAutoCompleteFacetViaMethod propertyAutoCompleteFacet = (PropertyAutoCompleteFacetViaMethod) facet;
+        assertEquals(propertyAutoCompleteMethod, propertyAutoCompleteFacet.getMethods().get(0));
+        
+        assertTrue(methodRemover.getRemovedMethodMethodCalls().contains(propertyAutoCompleteMethod));
+    }
 
     public void testDefaultFacetFoundAndMethodRemoved() {
         final PropertyDefaultFacetFactory facetFactory = new PropertyDefaultFacetFactory();

http://git-wip-us.apache.org/repos/asf/isis/blob/8af98a50/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItem.java
----------------------------------------------------------------------
diff --git a/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItem.java b/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItem.java
index 4635b4a..a8fea6c 100644
--- a/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItem.java
+++ b/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItem.java
@@ -19,6 +19,7 @@
 package dom.todo;
 
 import java.math.BigDecimal;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import java.util.SortedSet;