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 2012/12/05 00:41:10 UTC
[26/52] [partial] ISIS-188: consolidating isis-core
http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/plural/staticmethod/PluralFacetViaMethod.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/plural/staticmethod/PluralFacetViaMethod.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/plural/staticmethod/PluralFacetViaMethod.java
new file mode 100644
index 0000000..a0ea907
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/plural/staticmethod/PluralFacetViaMethod.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.progmodel.facets.object.plural.staticmethod;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.object.plural.PluralFacetAbstract;
+
+public class PluralFacetViaMethod extends PluralFacetAbstract {
+
+ public PluralFacetViaMethod(final String value, final FacetHolder holder) {
+ super(value, holder);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/plural/staticmethod/PluralMethodFacetFactory.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/plural/staticmethod/PluralMethodFacetFactory.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/plural/staticmethod/PluralMethodFacetFactory.java
new file mode 100644
index 0000000..52760a5
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/plural/staticmethod/PluralMethodFacetFactory.java
@@ -0,0 +1,54 @@
+/*
+ * 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.object.plural.staticmethod;
+
+import java.lang.reflect.Method;
+
+import org.apache.isis.core.metamodel.adapter.util.InvokeUtils;
+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;
+
+public class PluralMethodFacetFactory extends MethodPrefixBasedFacetFactoryAbstract {
+
+ private static final String PLURAL_NAME = "pluralName";
+
+ private static final String[] PREFIXES = { PLURAL_NAME, };
+
+ public PluralMethodFacetFactory() {
+ super(FeatureType.OBJECTS_ONLY, OrphanValidation.VALIDATE, PREFIXES);
+ }
+
+ @Override
+ public void process(final ProcessClassContext processClassContext) {
+ final Class<?> type = processClassContext.getCls();
+ final FacetHolder facetHolder = processClassContext.getFacetHolder();
+
+ final Method method = MethodFinderUtils.findMethod(type, MethodScope.CLASS, PLURAL_NAME, String.class, NO_PARAMETERS_TYPES);
+ if (method != null) {
+ final String name = (String) InvokeUtils.invokeStatic(method);
+ processClassContext.removeMethod(method);
+ FacetUtil.addFacet(new PluralFacetViaMethod(name, facetHolder));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/regex/RegExFacet.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/regex/RegExFacet.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/regex/RegExFacet.java
new file mode 100644
index 0000000..544ebaa
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/regex/RegExFacet.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.progmodel.facets.object.regex;
+
+import org.apache.isis.core.metamodel.facets.MultipleValueFacet;
+import org.apache.isis.core.metamodel.interactions.ValidatingInteractionAdvisor;
+import org.apache.isis.core.progmodel.facets.object.mask.MaskFacet;
+
+/**
+ * Whether the (string) property or a parameter must correspond to a specific
+ * regular expression.
+ *
+ * <p>
+ * In the standard Apache Isis Programming Model, corresponds to the
+ * <tt>@RegEx</tt> annotation.
+ *
+ * @see MaskFacet
+ */
+public interface RegExFacet extends MultipleValueFacet, ValidatingInteractionAdvisor {
+
+ public String validation();
+
+ public String format();
+
+ public boolean caseSensitive();
+
+ public boolean doesNotMatch(String proposed);
+
+ public String format(String text);
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/regex/RegExFacetAbstract.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/regex/RegExFacetAbstract.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/regex/RegExFacetAbstract.java
new file mode 100644
index 0000000..a3407f9
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/regex/RegExFacetAbstract.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.object.regex;
+
+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.FacetHolder;
+import org.apache.isis.core.metamodel.facets.MultipleValueFacetAbstract;
+import org.apache.isis.core.metamodel.interactions.ProposedHolder;
+import org.apache.isis.core.metamodel.interactions.ValidityContext;
+
+public abstract class RegExFacetAbstract extends MultipleValueFacetAbstract implements RegExFacet {
+
+ public static Class<? extends Facet> type() {
+ return RegExFacet.class;
+ }
+
+ private final String validation;
+ private final String format;
+ private final boolean caseSensitive;
+
+ public RegExFacetAbstract(final String validation, final String format, final boolean caseSensitive, final FacetHolder holder) {
+ super(type(), holder);
+ this.validation = validation;
+ this.format = format;
+ this.caseSensitive = caseSensitive;
+ }
+
+ @Override
+ public String validation() {
+ return validation;
+ }
+
+ @Override
+ public String format() {
+ return format;
+ }
+
+ @Override
+ public boolean caseSensitive() {
+ return caseSensitive;
+ }
+
+ // //////////////////////////////////////////////////////////
+
+ @Override
+ public String invalidates(final ValidityContext<? extends ValidityEvent> context) {
+ if (!(context instanceof ProposedHolder)) {
+ return null;
+ }
+ final ProposedHolder proposedHolder = (ProposedHolder) context;
+ final ObjectAdapter proposedArgument = proposedHolder.getProposed();
+ if (proposedArgument == null) {
+ return null;
+ }
+ final String titleString = proposedArgument.titleString();
+ if (!doesNotMatch(titleString)) {
+ return null;
+ }
+ return "Doesn't match pattern";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/regex/TitleFacetFormattedByRegex.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/regex/TitleFacetFormattedByRegex.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/regex/TitleFacetFormattedByRegex.java
new file mode 100644
index 0000000..3b4ebbf
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/regex/TitleFacetFormattedByRegex.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.object.regex;
+
+import org.apache.isis.applib.profiles.Localization;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facets.object.title.TitleFacetAbstract;
+
+public class TitleFacetFormattedByRegex extends TitleFacetAbstract {
+
+ private final RegExFacet regexFacet;
+
+ public TitleFacetFormattedByRegex(final RegExFacet regexFacet) {
+ super(regexFacet.getFacetHolder());
+ this.regexFacet = regexFacet;
+ }
+
+ @Override
+ public String title(final ObjectAdapter object, final Localization localization) {
+ return regexFacet.format(object.titleString());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/regex/annotation/RegExFacetAnnotationForType.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/regex/annotation/RegExFacetAnnotationForType.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/regex/annotation/RegExFacetAnnotationForType.java
new file mode 100644
index 0000000..87d770f
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/regex/annotation/RegExFacetAnnotationForType.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.progmodel.facets.object.regex.annotation;
+
+import java.util.regex.Pattern;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.progmodel.facets.object.regex.RegExFacetAbstract;
+
+public class RegExFacetAnnotationForType extends RegExFacetAbstract {
+
+ private final Pattern pattern;
+
+ public RegExFacetAnnotationForType(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/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/regex/annotation/RegExFacetAnnotationForTypeFacetFactory.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/regex/annotation/RegExFacetAnnotationForTypeFacetFactory.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/regex/annotation/RegExFacetAnnotationForTypeFacetFactory.java
new file mode 100644
index 0000000..a7fb5fd
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/regex/annotation/RegExFacetAnnotationForTypeFacetFactory.java
@@ -0,0 +1,53 @@
+/*
+ * 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.object.regex.annotation;
+
+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.progmodel.facets.object.regex.RegExFacet;
+
+public class RegExFacetAnnotationForTypeFacetFactory extends FacetFactoryAbstract {
+
+ public RegExFacetAnnotationForTypeFacetFactory() {
+ super(FeatureType.OBJECTS_ONLY);
+ }
+
+ @Override
+ public void process(final ProcessClassContext processClassContaxt) {
+ final RegEx annotation = Annotations.getAnnotation(processClassContaxt.getCls(), RegEx.class);
+ FacetUtil.addFacet(createRegexFacet(annotation, processClassContaxt.getFacetHolder()));
+ }
+
+ 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 RegExFacetAnnotationForType(validationExpression, formatExpression, caseSensitive, holder);
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/TitleFacetUsingParser.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/TitleFacetUsingParser.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/TitleFacetUsingParser.java
new file mode 100644
index 0000000..6f1b4de
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/TitleFacetUsingParser.java
@@ -0,0 +1,83 @@
+/*
+ * 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.object.title;
+
+import org.apache.isis.applib.adapters.Parser;
+import org.apache.isis.applib.profiles.Localization;
+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.object.title.TitleFacet;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjector;
+
+public class TitleFacetUsingParser extends FacetAbstract implements TitleFacet {
+
+ private final Parser parser;
+ private final ServicesInjector dependencyInjector;
+
+ public TitleFacetUsingParser(final Parser parser, final FacetHolder holder, final ServicesInjector dependencyInjector) {
+ super(TitleFacet.class, holder, Derivation.NOT_DERIVED);
+ this.parser = parser;
+ this.dependencyInjector = dependencyInjector;
+ }
+
+ @Override
+ protected String toStringValues() {
+ getDependencyInjector().injectServicesInto(parser);
+ return parser.toString();
+ }
+
+ @Override
+ public String title(final ObjectAdapter adapter, final Localization localization) {
+ if (adapter == null) {
+ return null;
+ }
+ final Object object = adapter.getObject();
+ if (object == null) {
+ return null;
+ }
+ getDependencyInjector().injectServicesInto(parser);
+ return parser.displayTitleOf(object, localization);
+ }
+
+ public String title(final ObjectAdapter adapter, final String usingMask) {
+ if (adapter == null) {
+ return null;
+ }
+ final Object object = adapter.getObject();
+ if (object == null) {
+ return null;
+ }
+ getDependencyInjector().injectServicesInto(parser);
+ return parser.displayTitleOf(object, usingMask);
+ }
+
+ // //////////////////////////////////////////////////////
+ // Dependencies (from constructor)
+ // //////////////////////////////////////////////////////
+
+ /**
+ * @return the dependencyInjector
+ */
+ public ServicesInjector getDependencyInjector() {
+ return dependencyInjector;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/TitleFacetViaTitleMethod.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/TitleFacetViaTitleMethod.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/TitleFacetViaTitleMethod.java
new file mode 100644
index 0000000..7f3a7f5
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/TitleFacetViaTitleMethod.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.progmodel.facets.object.title;
+
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import org.apache.isis.applib.profiles.Localization;
+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.object.title.TitleFacetAbstract;
+
+public class TitleFacetViaTitleMethod extends TitleFacetAbstract implements ImperativeFacet {
+
+ private static final Logger LOG = Logger.getLogger(TitleFacetViaTitleMethod.class);
+ private final Method method;
+
+ public TitleFacetViaTitleMethod(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 boolean impliesResolve() {
+ return true;
+ }
+
+ @Override
+ public boolean impliesObjectChanged() {
+ return false;
+ }
+
+ @Override
+ public String title(final ObjectAdapter owningAdapter, final Localization localization) {
+ try {
+ return (String) AdapterInvokeUtils.invoke(method, owningAdapter);
+ } catch (final RuntimeException ex) {
+ LOG.warn("title failure", ex);
+ return "Failed Title";
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/TitleFacetViaToStringMethod.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/TitleFacetViaToStringMethod.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/TitleFacetViaToStringMethod.java
new file mode 100644
index 0000000..e73c281
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/TitleFacetViaToStringMethod.java
@@ -0,0 +1,69 @@
+/*
+ * 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.object.title;
+
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.isis.applib.profiles.Localization;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.ImperativeFacet;
+import org.apache.isis.core.metamodel.facets.object.title.TitleFacetAbstract;
+
+public class TitleFacetViaToStringMethod extends TitleFacetAbstract implements ImperativeFacet {
+
+ private final Method method;
+
+ public TitleFacetViaToStringMethod(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 boolean impliesResolve() {
+ return true;
+ }
+
+ @Override
+ public boolean impliesObjectChanged() {
+ return false;
+ }
+
+ @Override
+ public String title(final ObjectAdapter object, final Localization localization) {
+ return object.getObject().toString();
+ }
+
+ @Override
+ public boolean isNoop() {
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/TitleMethodFacetFactory.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/TitleMethodFacetFactory.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/TitleMethodFacetFactory.java
new file mode 100644
index 0000000..b2a2a64
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/TitleMethodFacetFactory.java
@@ -0,0 +1,83 @@
+/*
+ * 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.object.title;
+
+import java.lang.reflect.Method;
+
+import org.apache.isis.core.commons.lang.JavaClassUtils;
+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.object.title.TitleFacet;
+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.fallback.FallbackFacetFactory;
+
+public class TitleMethodFacetFactory extends MethodPrefixBasedFacetFactoryAbstract {
+
+ private static final String TO_STRING = "toString";
+ private static final String TITLE = "title";
+
+ private static final String[] PREFIXES = { TO_STRING, TITLE, };
+
+ public TitleMethodFacetFactory() {
+ super(FeatureType.OBJECTS_ONLY, OrphanValidation.VALIDATE, PREFIXES);
+ }
+
+ /**
+ * If no title or toString can be used then will use Facets provided by
+ * {@link FallbackFacetFactory} instead.
+ */
+ @Override
+ public void process(final ProcessClassContext processClassContext) {
+ final Class<?> cls = processClassContext.getCls();
+ final FacetHolder facetHolder = processClassContext.getFacetHolder();
+
+ // may have a facet by virtue of @Title, say.
+ final TitleFacet existingTitleFacet = facetHolder.getFacet(TitleFacet.class);
+ if(existingTitleFacet != null && !existingTitleFacet.isNoop()) {
+ return;
+ }
+
+ Method method = MethodFinderUtils.findMethod(cls, MethodScope.OBJECT, TITLE, String.class, null);
+ if (method != null) {
+ processClassContext.removeMethod(method);
+ FacetUtil.addFacet(new TitleFacetViaTitleMethod(method, facetHolder));
+ return;
+ }
+
+
+ try {
+ method = MethodFinderUtils.findMethod(cls, MethodScope.OBJECT, TO_STRING, String.class, null);
+ if (method == null) {
+ return;
+ }
+ if (JavaClassUtils.isJavaClass(method.getDeclaringClass())) {
+ return;
+ }
+ processClassContext.removeMethod(method);
+ FacetUtil.addFacet(new TitleFacetViaToStringMethod(method, facetHolder));
+
+ } catch (final Exception e) {
+ return;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/annotation/HiddenFacetInTablesInferredFromTitleAnnotation.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/annotation/HiddenFacetInTablesInferredFromTitleAnnotation.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/annotation/HiddenFacetInTablesInferredFromTitleAnnotation.java
new file mode 100644
index 0000000..cb944c3
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/annotation/HiddenFacetInTablesInferredFromTitleAnnotation.java
@@ -0,0 +1,33 @@
+/*
+ * 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.object.title.annotation;
+
+import org.apache.isis.applib.annotation.When;
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.progmodel.facets.members.hidden.HiddenFacetImpl;
+
+public class HiddenFacetInTablesInferredFromTitleAnnotation extends HiddenFacetImpl {
+
+ public HiddenFacetInTablesInferredFromTitleAnnotation(FacetHolder holder) {
+ super(When.ALWAYS, Where.ALL_TABLES, holder);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/annotation/TitleAnnotationFacetFactory.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/annotation/TitleAnnotationFacetFactory.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/annotation/TitleAnnotationFacetFactory.java
new file mode 100644
index 0000000..2f53d7a
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/annotation/TitleAnnotationFacetFactory.java
@@ -0,0 +1,174 @@
+/*
+ * 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.object.title.annotation;
+
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.Lists;
+
+import org.apache.isis.applib.annotation.Disabled;
+import org.apache.isis.applib.annotation.Title;
+import org.apache.isis.core.metamodel.adapter.LocalizationProvider;
+import org.apache.isis.core.metamodel.adapter.LocalizationProviderAware;
+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.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;
+import org.apache.isis.core.metamodel.facets.FacetedMethod;
+import org.apache.isis.core.metamodel.facets.hide.HiddenFacet;
+import org.apache.isis.core.metamodel.methodutils.MethodScope;
+import org.apache.isis.core.progmodel.facets.MethodFinderUtils;
+import org.apache.isis.core.progmodel.facets.fallback.FallbackFacetFactory;
+import org.apache.isis.core.progmodel.facets.members.disabled.DisabledFacet;
+import org.apache.isis.core.progmodel.facets.members.disabled.annotation.DisabledFacetAnnotation;
+import org.apache.isis.core.progmodel.facets.object.title.annotation.TitleFacetViaTitleAnnotation.TitleComponent;
+
+public class TitleAnnotationFacetFactory extends FacetFactoryAbstract implements AdapterManagerAware, LocalizationProviderAware {
+
+ private AdapterManager adapterManager;
+ private LocalizationProvider localizationProvider;
+
+ public TitleAnnotationFacetFactory() {
+ super(FeatureType.OBJECTS_AND_PROPERTIES);
+ }
+
+ /**
+ * If no method tagged with {@link Title} annotation then will use Facets
+ * provided by {@link FallbackFacetFactory} instead.
+ */
+ @Override
+ public void process(final ProcessClassContext processClassContext) {
+ final Class<?> cls = processClassContext.getCls();
+ final FacetHolder facetHolder = processClassContext.getFacetHolder();
+
+ final List<Method> methods = MethodFinderUtils.findMethodsWithAnnotation(cls, MethodScope.OBJECT, Title.class);
+
+ Collections.sort(methods, new Comparator<Method>() {
+ Comparator<String> comparator = new SequenceComparator();
+
+ @Override
+ public int compare(final Method o1, final Method o2) {
+ final Title a1 = o1.getAnnotation(Title.class);
+ final Title a2 = o2.getAnnotation(Title.class);
+ return comparator.compare(a1.sequence(), a2.sequence());
+ }
+ });
+ if (methods.isEmpty()) {
+ return;
+ }
+ final List<TitleComponent> titleComponents = Lists.transform(methods, TitleComponent.FROM_METHOD);
+ FacetUtil.addFacet(new TitleFacetViaTitleAnnotation(titleComponents, facetHolder, adapterManager, localizationProvider));
+ }
+
+ /**
+ * Any property annotated with <tt>Title</tt> is hidden by default in tables.
+ */
+ @Override
+ public void process(final ProcessMethodContext processMethodContext) {
+ final FacetedMethod facetHolder = processMethodContext.getFacetHolder();
+ if(facetHolder.containsFacet(HiddenFacet.class)) {
+ // don't overwrite any facet already installed
+ return;
+ }
+ // otherwise, install hidden facet if this property annotated with @Title
+ final Title annotation = Annotations.getAnnotation(processMethodContext.getMethod(), Title.class);
+ FacetUtil.addFacet(create(annotation, facetHolder));
+ }
+
+ private Facet create(final Title annotation, final FacetHolder holder) {
+ return annotation != null ? new HiddenFacetInTablesInferredFromTitleAnnotation(holder) : null;
+ }
+
+
+
+
+ static class SequenceComparator implements Comparator<String> {
+
+ @Override
+ public int compare(final String sequence1, final String sequence2) {
+
+ final List<String> components1 = componentsFor(sequence1);
+ final List<String> components2 = componentsFor(sequence2);
+
+ final int size1 = components1.size();
+ final int size2 = components2.size();
+
+ if (size1 == 0 && size2 == 0) {
+ return 0;
+ }
+
+ // continue to loop until we run out of components.
+ int n = 0;
+ while (true) {
+ final int length = n + 1;
+ // check if run out of components in either side
+ if (size1 < length && size2 >= length) {
+ return -1; // o1 before o2
+ }
+ if (size2 < length && size1 >= length) {
+ return +1; // o2 before o1
+ }
+ if (size1 < length && size2 < length) {
+ // run out of components
+ return 0;
+ }
+ // we have this component on each side
+ int componentCompare = 0;
+ try {
+ final Integer c1 = Integer.valueOf(components1.get(n));
+ final Integer c2 = Integer.valueOf(components2.get(n));
+ componentCompare = c1.compareTo(c2);
+ } catch (final NumberFormatException nfe) {
+ // not integers compare as strings
+ componentCompare = components1.get(n).compareTo(components2.get(n));
+ }
+
+ if (componentCompare != 0) {
+ return componentCompare;
+ }
+ // this component is the same; lets look at the next
+ n++;
+ }
+ }
+
+ private static List<String> componentsFor(final String sequence) {
+ return Lists.newArrayList(Splitter.on('.').split(sequence));
+ }
+
+ }
+
+ @Override
+ public void setLocalizationProvider(final LocalizationProvider localizationProvider) {
+ this.localizationProvider = localizationProvider;
+ }
+
+ @Override
+ public void setAdapterManager(final AdapterManager adapterMap) {
+ this.adapterManager = adapterMap;
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/annotation/TitleFacetViaTitleAnnotation.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/annotation/TitleFacetViaTitleAnnotation.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/annotation/TitleFacetViaTitleAnnotation.java
new file mode 100644
index 0000000..384fc47
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/annotation/TitleFacetViaTitleAnnotation.java
@@ -0,0 +1,149 @@
+/*
+ * 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.object.title.annotation;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import com.google.common.base.Function;
+import com.google.common.base.Strings;
+
+import org.apache.log4j.Logger;
+
+import org.apache.isis.applib.annotation.Title;
+import org.apache.isis.applib.profiles.Localization;
+import org.apache.isis.core.metamodel.adapter.LocalizationProvider;
+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.object.title.TitleFacet;
+import org.apache.isis.core.metamodel.facets.object.title.TitleFacetAbstract;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+
+public class TitleFacetViaTitleAnnotation extends TitleFacetAbstract {
+
+ private static final Logger LOG = Logger.getLogger(TitleFacetViaTitleAnnotation.class);
+ private final List<TitleComponent> components;
+ private final AdapterManager adapterManager;
+ private final LocalizationProvider localizationProvider;
+
+ public static class TitleComponent {
+ public static final Function<? super Method, ? extends TitleComponent> FROM_METHOD = new Function<Method, TitleComponent>() {
+
+ @Override
+ public TitleComponent apply(final Method input) {
+ return TitleComponent.of(input);
+ }
+ };
+
+ private final String prepend;
+ private final String append;
+ private final Method method;
+ private final int abbreviateTo;
+
+ private TitleComponent(final String prepend, final String append, final Method method, final int abbreviateTo) {
+ super();
+ this.prepend = prepend;
+ this.append = append;
+ this.method = method;
+ this.abbreviateTo = abbreviateTo;
+ }
+
+ public String getPrepend() {
+ return prepend;
+ }
+
+ public String getAppend() {
+ return append;
+ }
+
+ public Method getMethod() {
+ return method;
+ }
+
+ public static TitleComponent of(final Method method) {
+ final Title annotation = method.getAnnotation(Title.class);
+ final String prepend = annotation != null ? annotation.prepend() : " ";
+ final String append = annotation != null ? annotation.append() : "";
+ final int abbreviateTo = annotation != null ? annotation.abbreviatedTo() : Integer.MAX_VALUE;
+ return new TitleComponent(prepend, append, method, abbreviateTo);
+ }
+ }
+
+ public TitleFacetViaTitleAnnotation(final List<TitleComponent> components, final FacetHolder holder, final AdapterManager adapterManager, final LocalizationProvider localizationProvider) {
+ super(holder);
+ this.components = components;
+ this.adapterManager = adapterManager;
+ this.localizationProvider = localizationProvider;
+ }
+
+ @Override
+ public String title(final ObjectAdapter owningAdapter, final Localization localization) {
+ final StringBuilder stringBuilder = new StringBuilder();
+
+ try {
+ for (final TitleComponent component : this.components) {
+ String title = null;
+ final Object titlePart = AdapterInvokeUtils.invoke(component.getMethod(), owningAdapter);
+ if (titlePart != null) {
+ // use either titleFacet...
+ title = titleOf(titlePart);
+ if (Strings.isNullOrEmpty(title)) {
+ // or the toString() otherwise
+ title = titlePart.toString().trim();
+ }
+ }
+ if (Strings.isNullOrEmpty(title)) {
+ continue;
+ }
+ stringBuilder.append(component.getPrepend());
+ stringBuilder.append(abbreviated(title, component.abbreviateTo));
+ stringBuilder.append(component.getAppend());
+ }
+
+ return stringBuilder.toString().trim();
+ } catch (final RuntimeException ex) {
+ LOG.warn("Title failure", ex);
+ return "Failed Title";
+ }
+ }
+
+ private String titleOf(final Object domainObject) {
+ final ObjectAdapter adapter = adapterManager.adapterFor(domainObject);
+ if (adapter == null) {
+ return null;
+ }
+ final ObjectSpecification returnSpec = adapter.getSpecification();
+ if (!returnSpec.containsFacet(TitleFacet.class)) {
+ return null;
+ }
+ return returnSpec.getTitle(adapter, localizationProvider.getLocalization());
+ }
+
+ public List<TitleComponent> getComponents() {
+ return components;
+ }
+
+ private static String abbreviated(final String str, final int maxLength) {
+ return str.length() < maxLength ? str : str.substring(0, maxLength - 3) + "...";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/typicallen/annotation/TypicalLengthAnnotationOnTypeFacetFactory.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/typicallen/annotation/TypicalLengthAnnotationOnTypeFacetFactory.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/typicallen/annotation/TypicalLengthAnnotationOnTypeFacetFactory.java
new file mode 100644
index 0000000..5962fce
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/typicallen/annotation/TypicalLengthAnnotationOnTypeFacetFactory.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.progmodel.facets.object.typicallen.annotation;
+
+import org.apache.isis.applib.annotation.TypicalLength;
+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.typicallen.TypicalLengthFacet;
+
+public class TypicalLengthAnnotationOnTypeFacetFactory extends FacetFactoryAbstract {
+
+ public TypicalLengthAnnotationOnTypeFacetFactory() {
+ super(FeatureType.OBJECTS_ONLY);
+ }
+
+ @Override
+ public void process(final ProcessClassContext processClassContaxt) {
+ final TypicalLength annotation = Annotations.getAnnotation(processClassContaxt.getCls(), TypicalLength.class);
+ FacetUtil.addFacet(create(annotation, processClassContaxt.getFacetHolder()));
+ }
+
+ private TypicalLengthFacet create(final TypicalLength annotation, final FacetHolder holder) {
+ return annotation != null ? new TypicalLengthFacetAnnotationOnType(annotation.value(), holder) : null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/typicallen/annotation/TypicalLengthFacetAnnotationOnType.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/typicallen/annotation/TypicalLengthFacetAnnotationOnType.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/typicallen/annotation/TypicalLengthFacetAnnotationOnType.java
new file mode 100644
index 0000000..bb70330
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/typicallen/annotation/TypicalLengthFacetAnnotationOnType.java
@@ -0,0 +1,39 @@
+/*
+ * 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.object.typicallen.annotation;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.typicallen.TypicalLengthFacetAbstract;
+
+public class TypicalLengthFacetAnnotationOnType extends TypicalLengthFacetAbstract {
+
+ private final int value;
+
+ public TypicalLengthFacetAnnotationOnType(final int value, final FacetHolder holder) {
+ super(holder, false);
+ this.value = value;
+ }
+
+ @Override
+ public int value() {
+ return value;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validate/ValidateObjectFacet.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validate/ValidateObjectFacet.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validate/ValidateObjectFacet.java
new file mode 100644
index 0000000..ab70505
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validate/ValidateObjectFacet.java
@@ -0,0 +1,55 @@
+/*
+ * 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.object.validate;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facets.object.callbacks.PersistingCallbackFacet;
+import org.apache.isis.core.metamodel.facets.object.callbacks.UpdatingCallbackFacet;
+import org.apache.isis.core.metamodel.interactions.ValidatingInteractionAdvisor;
+
+/**
+ * Mechanism for determining whether this object is in a valid state, for
+ * example so that it can be persisted or updated.
+ *
+ * <p>
+ * Even though all the properties of an object may themselves be valid, there
+ * could be inter-property dependencies which are invalid. For example
+ * <tt>fromDate</tt> > <tt>toDate</tt> would probably represent an invalid
+ * state.
+ *
+ * <p>
+ * In the standard Apache Isis Programming Model, typically corresponds to the
+ * <tt>validate</tt> method.
+ *
+ * @see PersistingCallbackFacet
+ * @see UpdatingCallbackFacet
+ */
+public interface ValidateObjectFacet extends Facet, ValidatingInteractionAdvisor {
+
+ /**
+ * The reason the object is invalid.
+ *
+ * <p>
+ * . If the object is actually valid, should return <tt>null</tt>.
+ */
+ public String invalidReason(ObjectAdapter adapter);
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validate/ValidateObjectFacetAbstract.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validate/ValidateObjectFacetAbstract.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validate/ValidateObjectFacetAbstract.java
new file mode 100644
index 0000000..8ddad6e
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validate/ValidateObjectFacetAbstract.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.progmodel.facets.object.validate;
+
+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.interactions.ObjectValidityContext;
+import org.apache.isis.core.metamodel.interactions.ValidityContext;
+
+public abstract class ValidateObjectFacetAbstract extends FacetAbstract implements ValidateObjectFacet {
+
+ public static Class<? extends Facet> type() {
+ return ValidateObjectFacet.class;
+ }
+
+ public ValidateObjectFacetAbstract(final FacetHolder holder) {
+ super(type(), holder, Derivation.NOT_DERIVED);
+ }
+
+ @Override
+ public String invalidates(final ValidityContext<? extends ValidityEvent> vc) {
+ if (!(vc instanceof ObjectValidityContext)) {
+ return null;
+ }
+ final ObjectAdapter toValidate = vc.getTarget();
+ return toValidate != null ? invalidReason(toValidate) : null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validate/method/ValidateObjectFacetViaValidateMethod.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validate/method/ValidateObjectFacetViaValidateMethod.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validate/method/ValidateObjectFacetViaValidateMethod.java
new file mode 100644
index 0000000..65d7dbf
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validate/method/ValidateObjectFacetViaValidateMethod.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.progmodel.facets.object.validate.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.progmodel.facets.object.validate.ValidateObjectFacetAbstract;
+
+public class ValidateObjectFacetViaValidateMethod extends ValidateObjectFacetAbstract implements ImperativeFacet {
+
+ private final Method method;
+
+ public ValidateObjectFacetViaValidateMethod(final Method method, final FacetHolder holder) {
+ super(holder);
+ this.method = method;
+ }
+
+ @Override
+ public List<Method> getMethods() {
+ return Collections.singletonList(method);
+ }
+
+ @Override
+ public boolean impliesResolve() {
+ return true;
+ }
+
+ @Override
+ public boolean impliesObjectChanged() {
+ return false;
+ }
+
+ @Override
+ public String invalidReason(final ObjectAdapter owningAdapter) {
+ return (String) AdapterInvokeUtils.invoke(method, owningAdapter);
+ }
+
+ @Override
+ protected String toStringValues() {
+ return "method=" + method;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validate/method/ValidateObjectViaValidateMethodFacetFactory.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validate/method/ValidateObjectViaValidateMethodFacetFactory.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validate/method/ValidateObjectViaValidateMethodFacetFactory.java
new file mode 100644
index 0000000..d0bc271
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validate/method/ValidateObjectViaValidateMethodFacetFactory.java
@@ -0,0 +1,52 @@
+/*
+ * 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.object.validate.method;
+
+import java.lang.reflect.Method;
+
+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;
+
+public class ValidateObjectViaValidateMethodFacetFactory extends MethodPrefixBasedFacetFactoryAbstract {
+
+ private static final String VALIDATE_PREFIX = "validate";
+
+ private static final String[] PREFIXES = { VALIDATE_PREFIX, };
+
+ public ValidateObjectViaValidateMethodFacetFactory() {
+ super(FeatureType.OBJECTS_ONLY, OrphanValidation.VALIDATE, PREFIXES);
+ }
+
+ @Override
+ public void process(final ProcessClassContext processClassContext) {
+ final Class<?> cls = processClassContext.getCls();
+ final FacetHolder facetHolder = processClassContext.getFacetHolder();
+
+ final Method method = MethodFinderUtils.findMethod(cls, MethodScope.OBJECT, VALIDATE_PREFIX, String.class, NO_PARAMETERS_TYPES);
+ if (method != null) {
+ FacetUtil.addFacet(new ValidateObjectFacetViaValidateMethod(method, facetHolder));
+ processClassContext.removeMethod(method);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validperspec/MustSatisfySpecificationOnTypeFacet.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validperspec/MustSatisfySpecificationOnTypeFacet.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validperspec/MustSatisfySpecificationOnTypeFacet.java
new file mode 100644
index 0000000..6cf748a
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validperspec/MustSatisfySpecificationOnTypeFacet.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.progmodel.facets.object.validperspec;
+
+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 MustSatisfySpecificationOnTypeFacet extends FacetAbstract implements ValidatingInteractionAdvisor {
+
+ public static Class<? extends Facet> type() {
+ return MustSatisfySpecificationOnTypeFacet.class;
+ }
+
+ private final List<Specification> specifications;
+
+ public MustSatisfySpecificationOnTypeFacet(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/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validperspec/MustSatisfySpecificationOnTypeFacetFactory.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validperspec/MustSatisfySpecificationOnTypeFacetFactory.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validperspec/MustSatisfySpecificationOnTypeFacetFactory.java
new file mode 100644
index 0000000..33f4e02
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validperspec/MustSatisfySpecificationOnTypeFacetFactory.java
@@ -0,0 +1,77 @@
+/*
+ * 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.object.validperspec;
+
+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 MustSatisfySpecificationOnTypeFacetFactory extends FacetFactoryAbstract {
+
+ public MustSatisfySpecificationOnTypeFacetFactory() {
+ super(FeatureType.OBJECTS_ONLY);
+ }
+
+ @Override
+ public void process(final ProcessClassContext processClassContaxt) {
+ FacetUtil.addFacet(create(processClassContaxt.getCls(), processClassContaxt.getFacetHolder()));
+ }
+
+ private Facet create(final Class<?> clazz, final FacetHolder holder) {
+ return create(Annotations.getAnnotation(clazz, MustSatisfy.class), holder);
+ }
+
+ private static 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 MustSatisfySpecificationOnTypeFacet(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/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validprops/ObjectValidPropertiesFacet.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validprops/ObjectValidPropertiesFacet.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validprops/ObjectValidPropertiesFacet.java
new file mode 100644
index 0000000..de25a65
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validprops/ObjectValidPropertiesFacet.java
@@ -0,0 +1,42 @@
+/*
+ * 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.object.validprops;
+
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facets.mandatory.MandatoryFacet;
+import org.apache.isis.core.metamodel.interactions.ObjectValidityContext;
+import org.apache.isis.core.metamodel.interactions.ValidatingInteractionAdvisor;
+
+/**
+ * Object-level {@link ValidatingInteractionAdvisor validator} that ensures that
+ * all {@link MandatoryFacet mandatory} properties are entered prior to
+ * persisting the object.
+ */
+public interface ObjectValidPropertiesFacet extends Facet, ValidatingInteractionAdvisor {
+
+ /**
+ * The reason the object is invalid.
+ *
+ * <p>
+ * . If the object is actually valid, should return <tt>null</tt>.
+ */
+ public String invalidReason(ObjectValidityContext context);
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validprops/ObjectValidPropertiesFacetAbstract.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validprops/ObjectValidPropertiesFacetAbstract.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validprops/ObjectValidPropertiesFacetAbstract.java
new file mode 100644
index 0000000..fb4d44c
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validprops/ObjectValidPropertiesFacetAbstract.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.progmodel.facets.object.validprops;
+
+import org.apache.isis.applib.events.ValidityEvent;
+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.ObjectValidityContext;
+import org.apache.isis.core.metamodel.interactions.ValidityContext;
+
+public abstract class ObjectValidPropertiesFacetAbstract extends FacetAbstract implements ObjectValidPropertiesFacet {
+
+ public static Class<? extends Facet> type() {
+ return ObjectValidPropertiesFacet.class;
+ }
+
+ public ObjectValidPropertiesFacetAbstract(final FacetHolder holder) {
+ super(type(), holder, Derivation.NOT_DERIVED);
+ }
+
+ @Override
+ public String invalidates(final ValidityContext<? extends ValidityEvent> ic) {
+ if (!(ic instanceof ObjectValidityContext)) {
+ return null;
+ }
+ final ObjectValidityContext validityContext = (ObjectValidityContext) ic;
+ return invalidReason(validityContext);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validprops/ObjectValidPropertiesFacetFactory.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validprops/ObjectValidPropertiesFacetFactory.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validprops/ObjectValidPropertiesFacetFactory.java
new file mode 100644
index 0000000..1c950b5
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validprops/ObjectValidPropertiesFacetFactory.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.progmodel.facets.object.validprops;
+
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facetapi.FeatureType;
+import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
+
+public class ObjectValidPropertiesFacetFactory extends FacetFactoryAbstract {
+
+ public ObjectValidPropertiesFacetFactory() {
+ super(FeatureType.OBJECTS_ONLY);
+ }
+
+ @Override
+ public void process(final ProcessClassContext processClassContaxt) {
+ FacetUtil.addFacet(new ObjectValidPropertiesFacetImpl(processClassContaxt.getFacetHolder()));
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validprops/ObjectValidPropertiesFacetImpl.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validprops/ObjectValidPropertiesFacetImpl.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validprops/ObjectValidPropertiesFacetImpl.java
new file mode 100644
index 0000000..16ba9d6
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/validprops/ObjectValidPropertiesFacetImpl.java
@@ -0,0 +1,71 @@
+/*
+ * 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.object.validprops;
+
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.interactions.ObjectValidityContext;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociationFilters;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+
+public class ObjectValidPropertiesFacetImpl extends ObjectValidPropertiesFacetAbstract {
+
+ // REVIEW: should provide this rendering context, rather than hardcoding.
+ // the net effect currently is that class members annotated with
+ // @Hidden(where=Where.ANYWHERE) or @Disabled(where=Where.ANYWHERE) will indeed
+ // be hidden/disabled, but will be visible/enabled (perhaps incorrectly)
+ // for any other value for Where
+ private final Where where = Where.ANYWHERE;
+
+ public ObjectValidPropertiesFacetImpl(final FacetHolder holder) {
+ super(holder);
+ }
+
+ @Override
+ public String invalidReason(final ObjectValidityContext context) {
+ final StringBuilder buf = new StringBuilder();
+ final ObjectAdapter adapter = context.getTarget();
+ for (final ObjectAssociation property : adapter.getSpecification().getAssociations(ObjectAssociationFilters.PROPERTIES)) {
+ // ignore hidden properties
+ if (property.isVisible(context.getSession(), adapter, where).isVetoed()) {
+ continue;
+ }
+ // ignore disabled properties
+ if (property.isUsable(context.getSession(), adapter, where).isVetoed()) {
+ continue;
+ }
+ final OneToOneAssociation otoa = (OneToOneAssociation) property;
+ final ObjectAdapter value = otoa.get(adapter);
+ if (otoa.isAssociationValid(adapter, value).isVetoed()) {
+ if (buf.length() > 0) {
+ buf.append(", ");
+ }
+ buf.append(property.getName());
+ }
+ }
+ if (buf.length() > 0) {
+ return "Invalid properties: " + buf.toString();
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/value/EqualByContentFacetViaValueSemantics.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/value/EqualByContentFacetViaValueSemantics.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/value/EqualByContentFacetViaValueSemantics.java
new file mode 100644
index 0000000..f82afc8
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/value/EqualByContentFacetViaValueSemantics.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.progmodel.facets.object.value;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.ebc.EqualByContentFacetAbstract;
+
+public class EqualByContentFacetViaValueSemantics extends EqualByContentFacetAbstract {
+
+ public EqualByContentFacetViaValueSemantics(final FacetHolder holder) {
+ super(holder);
+ }
+
+}