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 2014/07/11 12:56:40 UTC

[28/61] [partial] ISIS-831: digression: moving progmodel/facets into metamodel/facets

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/clear/PropertyClearFacetViaClearMethod.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/clear/PropertyClearFacetViaClearMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/clear/PropertyClearFacetViaClearMethod.java
new file mode 100644
index 0000000..86d979f
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/clear/PropertyClearFacetViaClearMethod.java
@@ -0,0 +1,74 @@
+/*
+ *  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.update.clear;
+
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+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;
+
+public class PropertyClearFacetViaClearMethod extends PropertyClearFacetAbstract implements ImperativeFacet {
+
+    private final Method method;
+
+    public PropertyClearFacetViaClearMethod(final Method method, final FacetHolder holder) {
+        super(holder);
+        this.method = method;
+    }
+
+    /**
+     * Returns a singleton list of the {@link Method} provided in the
+     * constructor.
+     */
+    @Override
+    public List<Method> getMethods() {
+        return Collections.singletonList(method);
+    }
+
+    @Override
+    public Intent getIntent(final Method method) {
+        return Intent.MODIFY_PROPERTY_SUPPORTING;
+    }
+
+    @Override
+    public boolean impliesResolve() {
+        return true;
+    }
+
+    @Override
+    public boolean impliesObjectChanged() {
+        return true;
+    }
+
+    @Override
+    public void clearProperty(final ObjectAdapter owningAdapter) {
+        AdapterInvokeUtils.invoke(method, owningAdapter);
+    }
+
+    @Override
+    protected String toStringValues() {
+        return "method=" + method;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/clear/PropertyClearFacetViaSetterMethod.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/clear/PropertyClearFacetViaSetterMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/clear/PropertyClearFacetViaSetterMethod.java
new file mode 100644
index 0000000..bf2b041
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/clear/PropertyClearFacetViaSetterMethod.java
@@ -0,0 +1,74 @@
+/*
+ *  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.update.clear;
+
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+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;
+
+public class PropertyClearFacetViaSetterMethod extends PropertyClearFacetAbstract implements ImperativeFacet {
+
+    private final Method method;
+
+    public PropertyClearFacetViaSetterMethod(final Method method, final FacetHolder holder) {
+        super(holder);
+        this.method = method;
+    }
+
+    /**
+     * Returns a singleton list of the {@link Method} provided in the
+     * constructor.
+     */
+    @Override
+    public List<Method> getMethods() {
+        return Collections.singletonList(method);
+    }
+
+    @Override
+    public Intent getIntent(final Method method) {
+        return Intent.MODIFY_PROPERTY;
+    }
+
+    @Override
+    public boolean impliesResolve() {
+        return true;
+    }
+
+    @Override
+    public boolean impliesObjectChanged() {
+        return true;
+    }
+
+    @Override
+    public void clearProperty(final ObjectAdapter owningAdapter) {
+        AdapterInvokeUtils.invoke(method, owningAdapter);
+    }
+
+    @Override
+    protected String toStringValues() {
+        return "method=" + method;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/init/PropertyInitializationFacet.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/init/PropertyInitializationFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/init/PropertyInitializationFacet.java
new file mode 100644
index 0000000..4f9e72f
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/init/PropertyInitializationFacet.java
@@ -0,0 +1,48 @@
+/*
+ *  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.update.init;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facets.propcoll.accessor.PropertyOrCollectionAccessorFacet;
+
+/**
+ * The mechanism by which the value of the property can be initialised.
+ * 
+ * <p>
+ * This differs from the {@link org.apache.isis.core.metamodel.facets.properties.update.modify.PropertySetterFacet} in that it is only called
+ * when object is set up (after persistence) and not every time a property
+ * changes; hence it will not be made part of a transaction.
+ * 
+ * <p>
+ * In the standard Apache Isis Programming Model, corresponds to invoking the
+ * mutator method for a property.
+ * 
+ * @see PropertyOrCollectionAccessorFacet
+ * @see org.apache.isis.core.metamodel.facets.properties.update.modify.PropertySetterFacet
+ * @see org.apache.isis.core.metamodel.facets.properties.update.clear.PropertyClearFacet
+ */
+public interface PropertyInitializationFacet extends Facet {
+
+    /**
+     * Sets the value of this property.
+     */
+    public void initProperty(ObjectAdapter inObject, ObjectAdapter value);
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/init/PropertyInitializationFacetAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/init/PropertyInitializationFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/init/PropertyInitializationFacetAbstract.java
new file mode 100644
index 0000000..1c061bf
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/init/PropertyInitializationFacetAbstract.java
@@ -0,0 +1,35 @@
+/*
+ *  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.update.init;
+
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facetapi.FacetAbstract;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+
+public abstract class PropertyInitializationFacetAbstract extends FacetAbstract implements PropertyInitializationFacet {
+
+    public static Class<? extends Facet> type() {
+        return PropertyInitializationFacet.class;
+    }
+
+    public PropertyInitializationFacetAbstract(final FacetHolder holder) {
+        super(type(), holder, Derivation.NOT_DERIVED);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/init/PropertyInitializationFacetViaSetterMethod.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/init/PropertyInitializationFacetViaSetterMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/init/PropertyInitializationFacetViaSetterMethod.java
new file mode 100644
index 0000000..31ee0a0
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/init/PropertyInitializationFacetViaSetterMethod.java
@@ -0,0 +1,76 @@
+/*
+ *  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.update.init;
+
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+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;
+
+public class PropertyInitializationFacetViaSetterMethod extends PropertyInitializationFacetAbstract implements ImperativeFacet {
+
+    private final Method method;
+
+    public PropertyInitializationFacetViaSetterMethod(final Method method, final FacetHolder holder) {
+        super(holder);
+        this.method = method;
+    }
+
+    /**
+     * Returns a singleton list of the {@link Method} provided in the
+     * constructor.
+     */
+    @Override
+    public List<Method> getMethods() {
+        return Collections.singletonList(method);
+    }
+
+    @Override
+    public Intent getIntent(final Method method) {
+        // LIMITATION: we cannot distinguish between setXxx being called for a modify or for an initialization
+        // so we just assume its a setter.
+        return Intent.MODIFY_PROPERTY;
+    }
+
+    @Override
+    public boolean impliesResolve() {
+        return false;
+    }
+
+    @Override
+    public boolean impliesObjectChanged() {
+        return false;
+    }
+
+    @Override
+    public void initProperty(final ObjectAdapter owningAdapter, final ObjectAdapter initialAdapter) {
+        AdapterInvokeUtils.invoke(method, owningAdapter, initialAdapter);
+    }
+
+    @Override
+    protected String toStringValues() {
+        return "method=" + method;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacet.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacet.java
new file mode 100644
index 0000000..99fddd3
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacet.java
@@ -0,0 +1,43 @@
+/*
+ *  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.update.modify;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facets.propcoll.accessor.PropertyOrCollectionAccessorFacet;
+
+/**
+ * The mechanism by which the value of the property can be set.
+ * 
+ * <p>
+ * In the standard Apache Isis Programming Model, corresponds to invoking the
+ * mutator method for a property.
+ * 
+ * @see PropertyOrCollectionAccessorFacet
+ * @see org.apache.isis.core.metamodel.facets.properties.update.clear.PropertyClearFacet
+ * @see org.apache.isis.core.metamodel.facets.properties.update.init.PropertyInitializationFacet
+ */
+public interface PropertySetterFacet extends Facet {
+
+    /**
+     * Sets the value of this property.
+     */
+    public void setProperty(ObjectAdapter inObject, ObjectAdapter value);
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacetAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacetAbstract.java
new file mode 100644
index 0000000..ea42897
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacetAbstract.java
@@ -0,0 +1,35 @@
+/*
+ *  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.update.modify;
+
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facetapi.FacetAbstract;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+
+public abstract class PropertySetterFacetAbstract extends FacetAbstract implements PropertySetterFacet {
+
+    public static Class<? extends Facet> type() {
+        return PropertySetterFacet.class;
+    }
+
+    public PropertySetterFacetAbstract(final FacetHolder holder) {
+        super(type(), holder, Derivation.NOT_DERIVED);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacetViaModifyMethod.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacetViaModifyMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacetViaModifyMethod.java
new file mode 100644
index 0000000..d728131
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacetViaModifyMethod.java
@@ -0,0 +1,74 @@
+/*
+ *  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.update.modify;
+
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+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;
+
+public class PropertySetterFacetViaModifyMethod extends PropertySetterFacetAbstract implements ImperativeFacet {
+
+    private final Method method;
+
+    public PropertySetterFacetViaModifyMethod(final Method method, final FacetHolder holder) {
+        super(holder);
+        this.method = method;
+    }
+
+    /**
+     * Returns a singleton list of the {@link Method} provided in the
+     * constructor.
+     */
+    @Override
+    public List<Method> getMethods() {
+        return Collections.singletonList(method);
+    }
+
+    @Override
+    public Intent getIntent(final Method method) {
+        return Intent.MODIFY_PROPERTY_SUPPORTING;
+    }
+
+    @Override
+    public boolean impliesResolve() {
+        return true;
+    }
+
+    @Override
+    public boolean impliesObjectChanged() {
+        return true;
+    }
+
+    @Override
+    public void setProperty(final ObjectAdapter adapter, final ObjectAdapter valueAdapter) {
+        AdapterInvokeUtils.invoke(method, adapter, valueAdapter);
+    }
+
+    @Override
+    protected String toStringValues() {
+        return "method=" + method;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacetViaSetterMethod.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacetViaSetterMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacetViaSetterMethod.java
new file mode 100644
index 0000000..b3b79ed
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacetViaSetterMethod.java
@@ -0,0 +1,74 @@
+/*
+ *  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.update.modify;
+
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+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;
+
+public class PropertySetterFacetViaSetterMethod extends PropertySetterFacetAbstract implements ImperativeFacet {
+
+    private final Method method;
+
+    public PropertySetterFacetViaSetterMethod(final Method method, final FacetHolder holder) {
+        super(holder);
+        this.method = method;
+    }
+
+    /**
+     * Returns a singleton list of the {@link Method} provided in the
+     * constructor.
+     */
+    @Override
+    public List<Method> getMethods() {
+        return Collections.singletonList(method);
+    }
+
+    @Override
+    public Intent getIntent(final Method method) {
+        return Intent.MODIFY_PROPERTY;
+    }
+
+    @Override
+    public boolean impliesResolve() {
+        return true;
+    }
+
+    @Override
+    public boolean impliesObjectChanged() {
+        return true;
+    }
+
+    @Override
+    public void setProperty(final ObjectAdapter adapter, final ObjectAdapter valueAdapter) {
+        AdapterInvokeUtils.invoke(method, adapter, valueAdapter);
+    }
+
+    @Override
+    protected String toStringValues() {
+        return "method=" + method;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/PropertyValidateFacet.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/PropertyValidateFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/PropertyValidateFacet.java
new file mode 100644
index 0000000..5e1d912
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/PropertyValidateFacet.java
@@ -0,0 +1,50 @@
+/*
+ *  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.validating;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facets.properties.update.modify.PropertySetterFacet;
+import org.apache.isis.core.metamodel.facets.properties.update.modify.PropertySetterFacetAbstract;
+import org.apache.isis.core.metamodel.interactions.ValidatingInteractionAdvisor;
+
+/**
+ * The mechanism by which the proposed value of a property can be validated,
+ * called immediately before {@link PropertySetterFacetAbstract setting the
+ * value}.
+ * 
+ * <p>
+ * In the standard Apache Isis Programming Model, corresponds to invoking the
+ * <tt>validateXxx</tt> method for a property with an accessor of
+ * <tt>getXxx</tt>.
+ * 
+ * @see PropertySetterFacet
+ */
+
+public interface PropertyValidateFacet extends Facet, ValidatingInteractionAdvisor {
+
+    /**
+     * The reason why the proposed value is invalid.
+     * 
+     * <p>
+     * Should return <tt>null</tt> if the value is in fact valid.
+     */
+    public String invalidReason(ObjectAdapter targetObject, ObjectAdapter proposedValue);
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/PropertyValidateFacetAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/PropertyValidateFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/PropertyValidateFacetAbstract.java
new file mode 100644
index 0000000..dfe7e8f
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/PropertyValidateFacetAbstract.java
@@ -0,0 +1,57 @@
+/*
+ *  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.validating;
+
+import org.apache.isis.applib.events.ValidityEvent;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+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.propparam.mandatory.MandatoryFacet;
+import org.apache.isis.core.metamodel.interactions.PropertyModifyContext;
+import org.apache.isis.core.metamodel.interactions.ValidityContext;
+
+public abstract class PropertyValidateFacetAbstract extends FacetAbstract implements PropertyValidateFacet {
+
+    public static Class<? extends Facet> type() {
+        return PropertyValidateFacet.class;
+    }
+
+    public PropertyValidateFacetAbstract(final FacetHolder holder) {
+        super(type(), holder, Derivation.NOT_DERIVED);
+    }
+
+    @Override
+    public String invalidates(final ValidityContext<? extends ValidityEvent> context) {
+        if (!(context instanceof PropertyModifyContext)) {
+            return null;
+        }
+        final PropertyModifyContext propertyModifyContext = (PropertyModifyContext) context;
+        ObjectAdapter proposed = propertyModifyContext.getProposed();
+        if(proposed == null) {
+            // skip validation if null value and optional property.
+            MandatoryFacet mandatoryFacet = getFacetHolder().getFacet(MandatoryFacet.class);
+            if(mandatoryFacet == null || mandatoryFacet.isNoop() || mandatoryFacet.isInvertedSemantics()) {
+                return null;
+            }
+        }
+        return invalidReason(propertyModifyContext.getTarget(), proposed);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/PropertyValidateFacetNone.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/PropertyValidateFacetNone.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/PropertyValidateFacetNone.java
new file mode 100644
index 0000000..f940fc3
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/PropertyValidateFacetNone.java
@@ -0,0 +1,47 @@
+/*
+ *  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.validating;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+
+public class PropertyValidateFacetNone extends PropertyValidateFacetAbstract {
+
+    public PropertyValidateFacetNone(final FacetHolder holder) {
+        super(holder);
+    }
+
+    /**
+     * Returns <tt>null</tt>, ie property is valid.
+     * 
+     * <p>
+     * Subclasses should override as required.
+     */
+    @Override
+    public String invalidReason(final ObjectAdapter inObject, final ObjectAdapter value) {
+        return null;
+    }
+
+    @Override
+    public boolean isNoop() {
+        return true;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/dflt/PropertyValidateFacetDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/dflt/PropertyValidateFacetDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/dflt/PropertyValidateFacetDefault.java
new file mode 100644
index 0000000..56a70a5
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/dflt/PropertyValidateFacetDefault.java
@@ -0,0 +1,49 @@
+/*
+ *  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.validating.dflt;
+
+import org.apache.isis.applib.events.ValidityEvent;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.FacetAbstract;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.properties.validating.PropertyValidateFacet;
+import org.apache.isis.core.metamodel.interactions.ValidityContext;
+
+/**
+ * Non checking property validation facet that provides default behaviour for
+ * all properties.
+ */
+public class PropertyValidateFacetDefault extends FacetAbstract implements PropertyValidateFacet {
+
+    @Override
+    public String invalidates(final ValidityContext<? extends ValidityEvent> ic) {
+        return null;
+    }
+
+    public PropertyValidateFacetDefault(final FacetHolder holder) {
+        super(PropertyValidateFacet.class, holder, Derivation.NOT_DERIVED);
+    }
+
+    @Override
+    public String invalidReason(final ObjectAdapter target, final ObjectAdapter proposedValue) {
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/dflt/PropertyValidateFacetDefaultFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/dflt/PropertyValidateFacetDefaultFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/dflt/PropertyValidateFacetDefaultFactory.java
new file mode 100644
index 0000000..3b47555
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/dflt/PropertyValidateFacetDefaultFactory.java
@@ -0,0 +1,59 @@
+/*
+ *  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.validating.dflt;
+
+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.facets.FacetFactory;
+import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
+import org.apache.isis.core.metamodel.facets.properties.validating.PropertyValidateFacet;
+import org.apache.isis.core.metamodel.specloader.facetprocessor.FacetProcessor;
+
+/**
+ * Simply installs a {@link org.apache.isis.core.metamodel.facets.properties.validating.PropertyValidateFacet} onto all properties.
+ * 
+ * <p>
+ * The idea is that this {@link FacetFactory} is included early on in the
+ * {@link FacetProcessor}, but other {@link org.apache.isis.core.metamodel.facets.properties.validating.PropertyValidateFacet}
+ * implementations will potentially replace these where the property is
+ * annotated or otherwise provides a validation mechanism.
+ */
+public class PropertyValidateFacetDefaultFactory extends FacetFactoryAbstract {
+
+    public PropertyValidateFacetDefaultFactory() {
+        super(FeatureType.PROPERTIES_ONLY);
+    }
+
+    @Override
+    public void process(final ProcessMethodContext processMethodContext) {
+        FacetUtil.addFacet(create(processMethodContext.getFacetHolder()));
+    }
+
+    @Override
+    public void processParams(final ProcessParameterContext processParameterContext) {
+        FacetUtil.addFacet(create(processParameterContext.getFacetHolder()));
+    }
+
+    private PropertyValidateFacet create(final FacetHolder holder) {
+        return new PropertyValidateFacetDefault(holder);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/maskannot/MaskFacetOnPropertyAnnotation.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/maskannot/MaskFacetOnPropertyAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/maskannot/MaskFacetOnPropertyAnnotation.java
new file mode 100644
index 0000000..a6ac033
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/maskannot/MaskFacetOnPropertyAnnotation.java
@@ -0,0 +1,51 @@
+/*
+ *  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.validating.maskannot;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.object.mask.MaskEvaluator;
+import org.apache.isis.core.metamodel.facets.object.mask.MaskFacetAbstract;
+
+public class MaskFacetOnPropertyAnnotation extends MaskFacetAbstract {
+    private final MaskEvaluator evaluator;
+
+    public MaskFacetOnPropertyAnnotation(final String outputMask, final String inputMask, final FacetHolder holder) {
+        super(outputMask, holder);
+        evaluator = inputMask == null ? null : new MaskEvaluator(inputMask);
+    }
+
+    @Override
+    public boolean doesNotMatch(final ObjectAdapter adapter) {
+        if (evaluator == null) {
+            return false;
+        } else {
+            if (adapter == null) {
+                return false;
+            }
+            final Object object = adapter.getObject();
+            if (object == null) {
+                return false;
+            }
+            return !evaluator.evaluate(object.toString());
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/maskannot/MaskFacetOnPropertyAnnotationFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/maskannot/MaskFacetOnPropertyAnnotationFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/maskannot/MaskFacetOnPropertyAnnotationFactory.java
new file mode 100644
index 0000000..697789f
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/maskannot/MaskFacetOnPropertyAnnotationFactory.java
@@ -0,0 +1,96 @@
+/*
+ *  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.validating.maskannot;
+
+import org.apache.isis.applib.annotation.Mask;
+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.facets.Annotations;
+import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
+import org.apache.isis.core.metamodel.facets.object.title.TitleFacet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.facets.object.mask.MaskFacet;
+import org.apache.isis.core.metamodel.facets.object.mask.TitleFacetBasedOnMask;
+
+public class MaskFacetOnPropertyAnnotationFactory extends FacetFactoryAbstract {
+
+    public MaskFacetOnPropertyAnnotationFactory() {
+        super(FeatureType.PROPERTIES_ONLY);
+    }
+
+    /**
+     * In readiness for supporting <tt>@Value</tt> in the future.
+     */
+    @Override
+    public void process(final ProcessClassContext processClassContaxt) {
+        final Mask annotation = Annotations.getAnnotation(processClassContaxt.getCls(), Mask.class);
+        FacetUtil.addFacet(createMaskFacet(annotation, processClassContaxt.getFacetHolder()));
+    }
+
+    @Override
+    public void process(final ProcessMethodContext processMethodContext) {
+        if (processMethodContext.getMethod().getReturnType() == void.class) {
+            return;
+        }
+
+        final Mask annotation = Annotations.getAnnotation(processMethodContext.getMethod(), Mask.class);
+        addMaskFacetAndCorrespondingTitleFacet(processMethodContext.getFacetHolder(), annotation, processMethodContext.getMethod().getReturnType());
+    }
+
+    @Override
+    public void processParams(final ProcessParameterContext processParameterContext) {
+        final Class<?>[] parameterTypes = processParameterContext.getMethod().getParameterTypes();
+        if (processParameterContext.getParamNum() >= parameterTypes.length) {
+            // ignore
+            return;
+        }
+
+        final java.lang.annotation.Annotation[] parameterAnnotations = Annotations.getParameterAnnotations(processParameterContext.getMethod())[processParameterContext.getParamNum()];
+        for (int i = 0; i < parameterAnnotations.length; i++) {
+            if (parameterAnnotations[i] instanceof Mask) {
+                final Mask annotation = (Mask) parameterAnnotations[i];
+                addMaskFacetAndCorrespondingTitleFacet(processParameterContext.getFacetHolder(), annotation, parameterTypes[i]);
+                return;
+            }
+        }
+    }
+
+    private MaskFacet createMaskFacet(final Mask annotation, final FacetHolder holder) {
+        return annotation != null ? new MaskFacetOnPropertyAnnotation(annotation.value(), null, holder) : null;
+    }
+
+    private boolean addMaskFacetAndCorrespondingTitleFacet(final FacetHolder holder, final Mask annotation, final Class<?> cls) {
+        final MaskFacet maskFacet = createMaskFacet(annotation, holder);
+        if (maskFacet == null) {
+            return false;
+        }
+        FacetUtil.addFacet(maskFacet);
+
+        final ObjectSpecification type = getSpecificationLoader().loadSpecification(cls);
+        final TitleFacet underlyingTitleFacet = type.getFacet(TitleFacet.class);
+        if (underlyingTitleFacet != null) {
+            final TitleFacet titleFacet = new TitleFacetBasedOnMask(maskFacet, underlyingTitleFacet);
+            FacetUtil.addFacet(titleFacet);
+        }
+        return true;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/maxlenannot/MaxLengthFacetOnPropertyAnnotation.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/maxlenannot/MaxLengthFacetOnPropertyAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/maxlenannot/MaxLengthFacetOnPropertyAnnotation.java
new file mode 100644
index 0000000..186759c
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/maxlenannot/MaxLengthFacetOnPropertyAnnotation.java
@@ -0,0 +1,31 @@
+/*
+ *  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.validating.maxlenannot;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.propparam.maxlen.MaxLengthFacetAbstract;
+
+public class MaxLengthFacetOnPropertyAnnotation extends MaxLengthFacetAbstract {
+
+    public MaxLengthFacetOnPropertyAnnotation(final int value, final FacetHolder holder) {
+        super(value, holder);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/maxlenannot/MaxLengthFacetOnPropertyAnnotationFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/maxlenannot/MaxLengthFacetOnPropertyAnnotationFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/maxlenannot/MaxLengthFacetOnPropertyAnnotationFactory.java
new file mode 100644
index 0000000..a90c71f
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/maxlenannot/MaxLengthFacetOnPropertyAnnotationFactory.java
@@ -0,0 +1,45 @@
+/*
+ *  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.validating.maxlenannot;
+
+import org.apache.isis.applib.annotation.MaxLength;
+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.facets.Annotations;
+import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
+import org.apache.isis.core.metamodel.facets.propparam.maxlen.MaxLengthFacet;
+
+public class MaxLengthFacetOnPropertyAnnotationFactory extends FacetFactoryAbstract {
+
+    public MaxLengthFacetOnPropertyAnnotationFactory() {
+        super(FeatureType.PROPERTIES_ONLY);
+    }
+
+    @Override
+    public void process(final ProcessMethodContext processMethodContext) {
+        final MaxLength annotation = Annotations.getAnnotation(processMethodContext.getMethod(), MaxLength.class);
+        FacetUtil.addFacet(create(annotation, processMethodContext.getFacetHolder()));
+    }
+
+    private MaxLengthFacet create(final MaxLength annotation, final FacetHolder holder) {
+        return annotation == null ? null : new MaxLengthFacetOnPropertyAnnotation(annotation.value(), holder);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethod.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethod.java
new file mode 100644
index 0000000..380b5e0
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethod.java
@@ -0,0 +1,75 @@
+/*
+ *  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.validating.method;
+
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+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.facets.properties.validating.PropertyValidateFacetAbstract;
+
+public class PropertyValidateFacetViaMethod extends PropertyValidateFacetAbstract implements ImperativeFacet {
+
+    private final Method method;
+
+    public PropertyValidateFacetViaMethod(final Method method, final FacetHolder holder) {
+        super(holder);
+        this.method = method;
+    }
+
+    /**
+     * Returns a singleton list of the {@link Method} provided in the
+     * constructor.
+     */
+    @Override
+    public List<Method> getMethods() {
+        return Collections.singletonList(method);
+    }
+
+    @Override
+    public Intent getIntent(final Method method) {
+        return Intent.CHECK_IF_VALID;
+    }
+
+    @Override
+    public boolean impliesResolve() {
+        return true;
+    }
+
+    @Override
+    public boolean impliesObjectChanged() {
+        return false;
+    }
+
+    @Override
+    public String invalidReason(final ObjectAdapter owningAdapter, final ObjectAdapter proposedAdapter) {
+        return (String) AdapterInvokeUtils.invoke(method, owningAdapter, proposedAdapter);
+    }
+
+    @Override
+    protected String toStringValues() {
+        return "method=" + method;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethodFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethodFactory.java
new file mode 100644
index 0000000..1c3a8bc
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethodFactory.java
@@ -0,0 +1,66 @@
+/*
+ *  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.validating.method;
+
+import java.lang.reflect.Method;
+
+import org.apache.isis.core.commons.lang.StringExtensions;
+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.metamodel.facets.MethodFinderUtils;
+import org.apache.isis.core.metamodel.facets.MethodPrefixBasedFacetFactoryAbstract;
+import org.apache.isis.core.metamodel.facets.MethodPrefixConstants;
+
+public class PropertyValidateFacetViaMethodFactory extends MethodPrefixBasedFacetFactoryAbstract {
+
+    private static final String[] PREFIXES = { MethodPrefixConstants.VALIDATE_PREFIX };
+
+    public PropertyValidateFacetViaMethodFactory() {
+        super(FeatureType.PROPERTIES_ONLY, OrphanValidation.VALIDATE, PREFIXES);
+    }
+
+    @Override
+    public void process(final ProcessMethodContext processMethodContext) {
+
+        attachValidateFacetIfValidateMethodIsFound(processMethodContext);
+    }
+
+    private void attachValidateFacetIfValidateMethodIsFound(final ProcessMethodContext processMethodContext) {
+
+        final Method getMethod = processMethodContext.getMethod();
+        final String capitalizedName = StringExtensions.asJavaBaseName(getMethod.getName());
+
+        final Class<?> returnType = getMethod.getReturnType();
+        final Class<?>[] paramTypes = new Class[] { returnType };
+
+        final Class<?> cls = processMethodContext.getCls();
+        final Method method = MethodFinderUtils.findMethod(cls, MethodScope.OBJECT, MethodPrefixConstants.VALIDATE_PREFIX + capitalizedName, String.class, paramTypes);
+        if (method == null) {
+            return;
+        }
+        processMethodContext.removeMethod(method);
+
+        final FacetHolder property = processMethodContext.getFacetHolder();
+        FacetUtil.addFacet(new PropertyValidateFacetViaMethod(method, property));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/mustsatisfyspec/MustSatisfySpecificationOnPropertyFacet.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/mustsatisfyspec/MustSatisfySpecificationOnPropertyFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/mustsatisfyspec/MustSatisfySpecificationOnPropertyFacet.java
new file mode 100644
index 0000000..d8626c6
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/mustsatisfyspec/MustSatisfySpecificationOnPropertyFacet.java
@@ -0,0 +1,63 @@
+/*
+ *  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.validating.mustsatisfyspec;
+
+import java.util.List;
+
+import org.apache.isis.applib.events.ValidityEvent;
+import org.apache.isis.applib.spec.Specification;
+import org.apache.isis.applib.util.ReasonBuffer;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+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.interactions.ProposedHolder;
+import org.apache.isis.core.metamodel.interactions.ValidatingInteractionAdvisor;
+import org.apache.isis.core.metamodel.interactions.ValidityContext;
+
+public class MustSatisfySpecificationOnPropertyFacet extends FacetAbstract implements ValidatingInteractionAdvisor {
+
+    public static Class<? extends Facet> type() {
+        return MustSatisfySpecificationOnPropertyFacet.class;
+    }
+
+    private final List<Specification> specifications;
+
+    public MustSatisfySpecificationOnPropertyFacet(final List<Specification> specifications, final FacetHolder holder) {
+        super(type(), holder, Derivation.NOT_DERIVED);
+        this.specifications = specifications;
+    }
+
+    @Override
+    public String invalidates(final ValidityContext<? extends ValidityEvent> validityContext) {
+        if (!(validityContext instanceof ProposedHolder)) {
+            return null;
+        }
+        final ProposedHolder proposedHolder = (ProposedHolder) validityContext;
+        final ObjectAdapter targetNO = proposedHolder.getProposed();
+        final Object targetObject = targetNO.getObject();
+        final ReasonBuffer buf = new ReasonBuffer();
+        for (final Specification specification : specifications) {
+            buf.append(specification.satisfies(targetObject));
+        }
+        return buf.getReason();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/mustsatisfyspec/MustSatisfySpecificationOnPropertyFacetFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/mustsatisfyspec/MustSatisfySpecificationOnPropertyFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/mustsatisfyspec/MustSatisfySpecificationOnPropertyFacetFactory.java
new file mode 100644
index 0000000..3dfa6ad
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/mustsatisfyspec/MustSatisfySpecificationOnPropertyFacetFactory.java
@@ -0,0 +1,78 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.properties.validating.mustsatisfyspec;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.isis.applib.annotation.MustSatisfy;
+import org.apache.isis.applib.spec.Specification;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+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.facets.Annotations;
+import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
+
+public class MustSatisfySpecificationOnPropertyFacetFactory extends FacetFactoryAbstract {
+
+    public MustSatisfySpecificationOnPropertyFacetFactory() {
+        super(FeatureType.PROPERTIES_ONLY);
+    }
+
+    @Override
+    public void process(final ProcessMethodContext processMethodContext) {
+        FacetUtil.addFacet(create(processMethodContext.getMethod(), processMethodContext.getFacetHolder()));
+    }
+
+    private Facet create(final Method method, final FacetHolder holder) {
+        return create(Annotations.getAnnotation(method, MustSatisfy.class), holder);
+    }
+
+    private Facet create(final MustSatisfy annotation, final FacetHolder holder) {
+        if (annotation == null) {
+            return null;
+        }
+        final Class<?>[] values = annotation.value();
+        final List<Specification> specifications = new ArrayList<Specification>();
+        for (final Class<?> value : values) {
+            final Specification specification = newSpecificationElseNull(value);
+            if (specification != null) {
+                specifications.add(specification);
+            }
+        }
+        return specifications.size() > 0 ? new MustSatisfySpecificationOnPropertyFacet(specifications, holder) : null;
+    }
+
+    private static Specification newSpecificationElseNull(final Class<?> value) {
+        if (!(Specification.class.isAssignableFrom(value))) {
+            return null;
+        }
+        try {
+            return (Specification) value.newInstance();
+        } catch (final InstantiationException e) {
+            return null;
+        } catch (final IllegalAccessException e) {
+            return null;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/regexannot/RegExFacetFacetOnPropertyAnnotationFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/regexannot/RegExFacetFacetOnPropertyAnnotationFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/regexannot/RegExFacetFacetOnPropertyAnnotationFactory.java
new file mode 100644
index 0000000..2a35bb0
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/regexannot/RegExFacetFacetOnPropertyAnnotationFactory.java
@@ -0,0 +1,75 @@
+/*
+ *  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.validating.regexannot;
+
+import org.apache.isis.applib.annotation.RegEx;
+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.facets.Annotations;
+import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
+import org.apache.isis.core.metamodel.facets.object.title.TitleFacet;
+import org.apache.isis.core.metamodel.facets.object.regex.RegExFacet;
+import org.apache.isis.core.metamodel.facets.object.regex.TitleFacetFormattedByRegex;
+
+public class RegExFacetFacetOnPropertyAnnotationFactory extends FacetFactoryAbstract {
+
+    public RegExFacetFacetOnPropertyAnnotationFactory() {
+        super(FeatureType.PROPERTIES_ONLY);
+    }
+
+    @Override
+    public void process(final ProcessMethodContext processMethodContext) {
+        final Class<?> returnType = processMethodContext.getMethod().getReturnType();
+        if (!Annotations.isString(returnType)) {
+            return;
+        }
+        final RegEx annotation = Annotations.getAnnotation(processMethodContext.getMethod(), RegEx.class);
+        addRegexFacetAndCorrespondingTitleFacet(processMethodContext.getFacetHolder(), annotation);
+    }
+
+    private void addRegexFacetAndCorrespondingTitleFacet(final FacetHolder holder, final RegEx annotation) {
+        final RegExFacet regexFacet = createRegexFacet(annotation, holder);
+        if (regexFacet == null) {
+            return;
+        }
+        FacetUtil.addFacet(regexFacet);
+
+        final TitleFacet titleFacet = createTitleFacet(regexFacet);
+        FacetUtil.addFacet(titleFacet);
+    }
+
+    private RegExFacet createRegexFacet(final RegEx annotation, final FacetHolder holder) {
+        if (annotation == null) {
+            return null;
+        }
+
+        final String validationExpression = annotation.validation();
+        final boolean caseSensitive = annotation.caseSensitive();
+        final String formatExpression = annotation.format();
+
+        return new RegExFacetOnPropertyAnnotation(validationExpression, formatExpression, caseSensitive, holder);
+    }
+
+    private TitleFacet createTitleFacet(final RegExFacet regexFacet) {
+        return new TitleFacetFormattedByRegex(regexFacet);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/regexannot/RegExFacetOnPropertyAnnotation.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/regexannot/RegExFacetOnPropertyAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/regexannot/RegExFacetOnPropertyAnnotation.java
new file mode 100644
index 0000000..6f7f1b2
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/regexannot/RegExFacetOnPropertyAnnotation.java
@@ -0,0 +1,59 @@
+/*
+ *  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.validating.regexannot;
+
+import java.util.regex.Pattern;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.object.regex.RegExFacetAbstract;
+
+public class RegExFacetOnPropertyAnnotation extends RegExFacetAbstract {
+
+    private final Pattern pattern;
+
+    public RegExFacetOnPropertyAnnotation(final String validation, final String format, final boolean caseSensitive, final FacetHolder holder) {
+        super(validation, format, caseSensitive, holder);
+        pattern = Pattern.compile(validation(), patternFlags());
+    }
+
+    @Override
+    public String format(final String text) {
+        if (text == null) {
+            return "<not a string>";
+        }
+        if (format() == null || format().length() == 0) {
+            return text;
+        }
+        return pattern.matcher(text).replaceAll(format());
+    }
+
+    @Override
+    public boolean doesNotMatch(final String text) {
+        if (text == null) {
+            return true;
+        }
+        return !pattern.matcher(text).matches();
+    }
+
+    private int patternFlags() {
+        return !caseSensitive() ? Pattern.CASE_INSENSITIVE : 0;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propparam/choices/ChoicesFacet.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propparam/choices/ChoicesFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propparam/choices/ChoicesFacet.java
new file mode 100644
index 0000000..335d9fc
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propparam/choices/ChoicesFacet.java
@@ -0,0 +1,46 @@
+/*
+ *  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.propparam.choices;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+
+public interface ChoicesFacet extends Facet {
+
+    /**
+     * Gets a set of choices for this object.
+     */
+    public Object[] getChoices(ObjectAdapter adapter);
+
+    
+    
+    public static class Util {
+
+        private Util() {
+        }
+
+        public static boolean hasChoices(final ObjectSpecification specification) {
+            return specification.getFacet(ChoicesFacet.class) != null;
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propparam/choices/ChoicesFacetAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propparam/choices/ChoicesFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propparam/choices/ChoicesFacetAbstract.java
new file mode 100644
index 0000000..3c0e293
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propparam/choices/ChoicesFacetAbstract.java
@@ -0,0 +1,36 @@
+/*
+ *  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.propparam.choices;
+
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facetapi.FacetAbstract;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+
+public abstract class ChoicesFacetAbstract extends FacetAbstract implements ChoicesFacet {
+
+    public static Class<? extends Facet> type() {
+        return ChoicesFacet.class;
+    }
+
+    public ChoicesFacetAbstract(final FacetHolder holder) {
+        super(type(), holder, Derivation.NOT_DERIVED);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propparam/fallback/MaxLengthFacetUnlimited.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propparam/fallback/MaxLengthFacetUnlimited.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propparam/fallback/MaxLengthFacetUnlimited.java
new file mode 100644
index 0000000..6624e25
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propparam/fallback/MaxLengthFacetUnlimited.java
@@ -0,0 +1,46 @@
+/*
+ *  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.propparam.fallback;
+
+import org.apache.isis.applib.events.ValidityEvent;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.propparam.maxlen.MaxLengthFacetAbstract;
+import org.apache.isis.core.metamodel.interactions.ValidityContext;
+
+public class MaxLengthFacetUnlimited extends MaxLengthFacetAbstract {
+
+    public MaxLengthFacetUnlimited(final FacetHolder holder) {
+        super(Integer.MAX_VALUE, holder);
+    }
+
+    /**
+     * No limit to maximum length.
+     */
+    @Override
+    public String invalidates(final ValidityContext<? extends ValidityEvent> context) {
+        return null;
+    }
+
+    @Override
+    public boolean isNoop() {
+        return true;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propparam/fallback/MultiLineFacetNone.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propparam/fallback/MultiLineFacetNone.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propparam/fallback/MultiLineFacetNone.java
new file mode 100644
index 0000000..5a41bc6
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propparam/fallback/MultiLineFacetNone.java
@@ -0,0 +1,36 @@
+/*
+ *  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.propparam.fallback;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.propparam.multiline.MultiLineFacetAbstract;
+
+public class MultiLineFacetNone extends MultiLineFacetAbstract {
+
+    public MultiLineFacetNone(final boolean preventWrapping, final FacetHolder holder) {
+        super(1, preventWrapping, holder);
+    }
+
+    @Override
+    public boolean isNoop() {
+        return true;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propparam/mandatory/MandatoryFacet.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propparam/mandatory/MandatoryFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propparam/mandatory/MandatoryFacet.java
new file mode 100644
index 0000000..fd13f15
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propparam/mandatory/MandatoryFacet.java
@@ -0,0 +1,58 @@
+/*
+ *  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.propparam.mandatory;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.MarkerFacet;
+import org.apache.isis.core.metamodel.interactions.ValidatingInteractionAdvisor;
+
+/**
+ * Whether a property or a parameter is mandatory (not optional).
+ * 
+ * <p>
+ * For a mandatory property, the object cannot be saved/updated without the
+ * value being provided. For a mandatory parameter, the action cannot be invoked
+ * without the value being provided.
+ * 
+ * <p>
+ * In the standard Apache Isis Programming Model, specify mandatory by
+ * <i>omitting</i> the <tt>@Optional</tt> annotation.
+ */
+public interface MandatoryFacet extends MarkerFacet, ValidatingInteractionAdvisor {
+
+    /**
+     * Whether this value is required but has not been provided (and is
+     * therefore invalid).
+     * 
+     * <p>
+     * If the value has been provided, <i>or</i> if the property or parameter is
+     * not required, then will return <tt>false</tt>.
+     */
+    boolean isRequiredButNull(ObjectAdapter adapter);
+
+    /**
+     * Indicates that the implementation is overridding the usual semantics, in
+     * other words that the {@link FacetHolder} to which this {@link Facet} is
+     * attached is <i>not</i> mandatory.
+     */
+    public boolean isInvertedSemantics();
+}