ISIS-903: updating ImperativeFacets for validation/disabling and also the title 
method so that they can return TranslatableString as well as regular String.

Also:
- added new SimpleObject#updateName action with validation and a default; added 
SimpleObject#title()
- reworked the simpleapp's integ tests into "Dublin" style, added new integ 
tests to check that the translation.pot file is correctly written to with these.


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

Branch: refs/heads/master
Commit: 3f5fbc44801fd7614b437b8be91277134f1bccbf
Parents: 54b39c7
Author: Dan Haywood <[email protected]>
Authored: Wed Feb 18 01:52:44 2015 +0000
Committer: Dan Haywood <[email protected]>
Committed: Wed Feb 18 14:07:48 2015 +0000

----------------------------------------------------------------------
 .../applib/fixturescripts/FixtureScript.java    |   8 +-
 .../metamodel/facets/MethodFinderUtils.java     |  15 ++
 .../method/ActionValidationFacetViaMethod.java  |  18 ++-
 .../ActionValidationFacetViaMethodFactory.java  |  33 +++-
 .../facets/all/i18n/I18nFacetFactory.java       | 160 -------------------
 .../all/i18n/TranslationFacetFactory.java       | 160 +++++++++++++++++++
 ...nAddToRemoveFromAndValidateFacetFactory.java |  59 +++++--
 .../CollectionValidateAddToFacetViaMethod.java  |  18 ++-
 ...lectionValidateRemoveFromFacetViaMethod.java |  18 ++-
 .../method/DisableForContextFacetViaMethod.java |  21 ++-
 .../DisableForContextFacetViaMethodFactory.java |  29 +++-
 .../method/DisabledObjectFacetViaMethod.java    |  25 ++-
 .../DisabledObjectFacetViaMethodFactory.java    |  35 ++--
 .../methods/TitleFacetViaMethodsFactory.java    |  28 +++-
 .../title/methods/TitleFacetViaTitleMethod.java |  20 ++-
 .../method/ValidateObjectFacetMethod.java       |  18 ++-
 .../ValidateObjectFacetMethodFactory.java       |  24 ++-
 .../PropertyAutoCompleteFacetMethodFactory.java |   2 +-
 .../PropertyChoicesFacetViaMethodFactory.java   |   2 +-
 .../method/PropertyValidateFacetViaMethod.java  |  18 ++-
 .../PropertyValidateFacetViaMethodFactory.java  |  34 +++-
 .../metamodel/services/i18n/po/PoReader.java    |  18 ++-
 .../metamodel/services/i18n/po/PoWriter.java    |   2 +-
 .../dflt/ProgrammingModelFacetsJava5.java       |   4 +-
 .../ident/title/TitleFacetViaMethodTest.java    |  10 +-
 ...rapperFactoryAbstractTest_wrappedObject.java |   4 +-
 .../src/main/java/dom/simple/SimpleObject.java  |  47 +++++-
 .../java/dom/simple/SimpleObject.layout.json    |  52 +++---
 .../simple/SimpleObjectsFixturesService.java    |   6 +-
 .../simple/objects/SimpleObjectAbstract.java    |  36 -----
 .../simple/objects/SimpleObjectCreate.java      |  70 ++++++++
 .../simple/objects/SimpleObjectForBar.java      |  31 ----
 .../simple/objects/SimpleObjectForBaz.java      |  31 ----
 .../simple/objects/SimpleObjectForFoo.java      |  31 ----
 .../simple/scenario/RecreateSimpleObjects.java  |  91 +++++++++++
 .../simple/scenario/SimpleObjectsFixture.java   |  45 ------
 .../integration/glue/BootstrappingGlue.java     |  11 --
 .../integration/glue/CatalogOfFixturesGlue.java |  19 +--
 .../glue/InMemoryDBForSimpleApp.java            |  40 -----
 .../glue/simple/SimpleObjectGlue.java           |  46 ------
 .../SimpleObjectSpec_listAllAndCreate.feature   |  11 --
 .../tests/smoke/SimpleObjectIntegTest.java      | 132 +++++++++++++++
 .../tests/smoke/SimpleObjectTest.java           |  82 ----------
 .../tests/smoke/SimpleObjectsIntegTest.java     | 146 +++++++++++++++++
 .../tests/smoke/SimpleObjectsTest.java          | 148 -----------------
 .../src/main/webapp/WEB-INF/isis.properties     |   4 +-
 .../src/main/webapp/WEB-INF/translations.po     |  98 ++----------
 47 files changed, 1064 insertions(+), 896 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/3f5fbc44/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/FixtureScript.java
----------------------------------------------------------------------
diff --git 
a/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/FixtureScript.java
 
b/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/FixtureScript.java
index d79e3c9..e23cffb 100644
--- 
a/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/FixtureScript.java
+++ 
b/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/FixtureScript.java
@@ -456,8 +456,8 @@ public abstract class FixtureScript
          * that are {@link 
org.apache.isis.applib.fixturescripts.FixtureScript.ExecutionContext#addResult(FixtureScript,
 Object)} added),
          * uses a key that is derived from the fixture's class name.
          */
-         public void executeChild(final FixtureScript callingFixtureScript, 
final FixtureScript childFixtureScript) {
-            executeChild(callingFixtureScript, null, childFixtureScript);
+         public <T extends FixtureScript> T executeChild(final FixtureScript 
callingFixtureScript, final T childFixtureScript) {
+            return executeChild(callingFixtureScript, null, 
childFixtureScript);
         }
 
         /**
@@ -465,7 +465,7 @@ public abstract class FixtureScript
          * that are {@link 
org.apache.isis.applib.fixturescripts.FixtureScript.ExecutionContext#addResult(FixtureScript,
 Object)} added),
          * uses a key that overriding the default name of the fixture script 
with one more meaningful in the context of this fixture.
          */
-        public void executeChild(final FixtureScript callingFixtureScript, 
final String localNameOverride, final FixtureScript childFixtureScript) {
+        public <T extends FixtureScript> T executeChild(final FixtureScript 
callingFixtureScript, final String localNameOverride, final T 
childFixtureScript) {
 
             
childFixtureScript.setParentPath(callingFixtureScript.pathWith(""));
             if(localNameOverride != null) {
@@ -473,6 +473,8 @@ public abstract class FixtureScript
             }
             
callingFixtureScript.getContainer().injectServicesInto(childFixtureScript);
             executeChildIfNotAlready(childFixtureScript);
+
+            return childFixtureScript;
         }
 
 

http://git-wip-us.apache.org/repos/asf/isis/blob/3f5fbc44/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/MethodFinderUtils.java
----------------------------------------------------------------------
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/MethodFinderUtils.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/MethodFinderUtils.java
index d2a9cb6..96621c8 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/MethodFinderUtils.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/MethodFinderUtils.java
@@ -101,6 +101,21 @@ public final class MethodFinderUtils {
         return method;
     }
 
+    public static Method findMethod(
+            final Class<?> type,
+            final MethodScope methodScope,
+            final String name,
+            final Class<?>[] returnTypes,
+            final Class<?>[] paramTypes) {
+        for (Class<?> returnType : returnTypes) {
+            final Method method = findMethod(type, methodScope, name, 
returnType, paramTypes);
+            if(method != null) {
+                return method;
+            }
+        }
+        return null;
+    }
+
     protected static boolean doesNotMatchScope(final MethodScope methodScope, 
final Method method) {
         return methodScope.doesNotMatchScope(method);
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/3f5fbc44/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethod.java
----------------------------------------------------------------------
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethod.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethod.java
index 8393b28..fed4062 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethod.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethod.java
@@ -23,6 +23,8 @@ import java.lang.reflect.Method;
 import java.util.Collections;
 import java.util.List;
 
+import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.ImperativeFacet;
@@ -31,10 +33,14 @@ import 
org.apache.isis.core.metamodel.facets.actions.validate.ActionValidationFa
 public class ActionValidationFacetViaMethod extends 
ActionValidationFacetAbstract implements ImperativeFacet {
 
     private final Method method;
+    private final TranslationService translationService;
+    private final String translationContext;
 
-    public ActionValidationFacetViaMethod(final Method method, final 
FacetHolder holder) {
+    public ActionValidationFacetViaMethod(final Method method, final 
TranslationService translationService, final String translationContext, final 
FacetHolder holder) {
         super(holder);
         this.method = method;
+        this.translationService = translationService;
+        this.translationContext = translationContext;
     }
 
     /**
@@ -63,7 +69,15 @@ public class ActionValidationFacetViaMethod extends 
ActionValidationFacetAbstrac
 
     @Override
     public String invalidReason(final ObjectAdapter owningAdapter, final 
ObjectAdapter[] proposedArgumentAdapters) {
-        return (String) ObjectAdapter.InvokeUtils.invoke(method, 
owningAdapter, proposedArgumentAdapters);
+        final Object returnValue = ObjectAdapter.InvokeUtils.invoke(method, 
owningAdapter, proposedArgumentAdapters);
+        if(returnValue instanceof String) {
+            return (String) returnValue;
+        }
+        if(returnValue instanceof TranslatableString) {
+            final TranslatableString ts = (TranslatableString) returnValue;
+            return ts.translate(translationService, translationContext);
+        }
+        return null;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/isis/blob/3f5fbc44/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethodFactory.java
----------------------------------------------------------------------
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethodFactory.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethodFactory.java
index 03e8eb6..93d53b7 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethodFactory.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethodFactory.java
@@ -20,22 +20,25 @@
 package org.apache.isis.core.metamodel.facets.actions.validate.method;
 
 import java.lang.reflect.Method;
-
+import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.core.commons.lang.StringExtensions;
 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.methodutils.MethodScope;
+import org.apache.isis.core.metamodel.facetapi.IdentifiedHolder;
 import org.apache.isis.core.metamodel.facets.MethodFinderUtils;
 import 
org.apache.isis.core.metamodel.facets.MethodPrefixBasedFacetFactoryAbstract;
 import org.apache.isis.core.metamodel.facets.MethodPrefixConstants;
 import 
org.apache.isis.core.metamodel.facets.actions.validate.ActionValidationFacet;
+import org.apache.isis.core.metamodel.methodutils.MethodScope;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjector;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjectorAware;
 
 /**
  * Sets up {@link ActionValidationFacet}.
  */
-public class ActionValidationFacetViaMethodFactory extends 
MethodPrefixBasedFacetFactoryAbstract {
+public class ActionValidationFacetViaMethodFactory extends 
MethodPrefixBasedFacetFactoryAbstract implements ServicesInjectorAware {
 
     private static final String[] PREFIXES = { 
MethodPrefixConstants.VALIDATE_PREFIX };
 
@@ -65,14 +68,30 @@ public class ActionValidationFacetViaMethodFactory extends 
MethodPrefixBasedFace
         final Class<?>[] paramTypes = actionMethod.getParameterTypes();
         final MethodScope onClass = MethodScope.scopeFor(actionMethod);
 
-        final Method validateMethod = MethodFinderUtils.findMethod(cls, 
onClass, MethodPrefixConstants.VALIDATE_PREFIX + capitalizedName, String.class, 
paramTypes);
+        final Method validateMethod = MethodFinderUtils.findMethod(
+                cls, onClass,
+                MethodPrefixConstants.VALIDATE_PREFIX + capitalizedName,
+                new Class<?>[]{String.class, TranslatableString.class},
+                paramTypes);
         if (validateMethod == null) {
             return;
         }
         processMethodContext.removeMethod(validateMethod);
 
-        final FacetHolder facetedMethod = 
processMethodContext.getFacetHolder();
-        FacetUtil.addFacet(new ActionValidationFacetViaMethod(validateMethod, 
facetedMethod));
+        final IdentifiedHolder facetedMethod = 
processMethodContext.getFacetHolder();
+        final TranslationService translationService = 
servicesInjector.lookupService(TranslationService.class);
+        // sadness: same as in TranslationFactory
+        final String translationContext = 
facetedMethod.getIdentifier().toClassAndNameIdentityString();
+        final ActionValidationFacetViaMethod facet = new 
ActionValidationFacetViaMethod(validateMethod, translationService, 
translationContext, facetedMethod);
+        FacetUtil.addFacet(facet);
     }
 
+    // //////////////////////////////////////
+
+    private ServicesInjector servicesInjector;
+
+    @Override
+    public void setServicesInjector(final ServicesInjector servicesInjector) {
+        this.servicesInjector = servicesInjector;
+    }
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/3f5fbc44/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/i18n/I18nFacetFactory.java
----------------------------------------------------------------------
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/i18n/I18nFacetFactory.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/i18n/I18nFacetFactory.java
deleted file mode 100644
index dfa3d5e..0000000
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/i18n/I18nFacetFactory.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.core.metamodel.facets.all.i18n;
-
-
-import com.google.common.base.Strings;
-import org.apache.isis.applib.services.i18n.LocaleProvider;
-import org.apache.isis.applib.services.i18n.TranslationService;
-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.facetapi.IdentifiedHolder;
-import org.apache.isis.core.metamodel.facets.ContributeeMemberFacetFactory;
-import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
-import org.apache.isis.core.metamodel.facets.all.describedas.DescribedAsFacet;
-import org.apache.isis.core.metamodel.facets.all.named.NamedFacet;
-import org.apache.isis.core.metamodel.runtimecontext.ServicesInjector;
-import org.apache.isis.core.metamodel.runtimecontext.ServicesInjectorAware;
-
-public class I18nFacetFactory extends FacetFactoryAbstract implements 
ContributeeMemberFacetFactory, ServicesInjectorAware {
-
-    private ServicesInjector servicesInjector;
-
-    private TranslationService translationService;
-    private LocaleProvider localeProvider;
-
-    public I18nFacetFactory() {
-        super(FeatureType.EVERYTHING);
-    }
-
-    @Override
-    public void process(final ProcessClassContext processClassContext) {
-        final FacetHolder facetHolder = processClassContext.getFacetHolder();
-        if(facetHolder instanceof IdentifiedHolder) {
-            final IdentifiedHolder holder = (IdentifiedHolder) facetHolder;
-            final String context = 
holder.getIdentifier().toClassIdentityString();
-            translateName(holder, context);
-            translateDescription(holder, context);
-        }
-    }
-
-    @Override
-    public void process(final ProcessMethodContext processMethodContext) {
-        final IdentifiedHolder holder = processMethodContext.getFacetHolder();
-
-        final String context = 
holder.getIdentifier().toClassAndNameIdentityString();
-        translateName(holder, context);
-        translateDescription(holder, context);
-    }
-
-    @Override
-    public void processParams(final ProcessParameterContext 
processParameterContext) {
-        final IdentifiedHolder holder = 
processParameterContext.getFacetHolder();
-
-        final String context = holder.getIdentifier().toFullIdentityString();
-        translateName(holder, context);
-        translateDescription(holder, context);
-    }
-
-    @Override
-    public void process(final ProcessContributeeMemberContext 
processMemberContext) {
-        final IdentifiedHolder holder = processMemberContext.getFacetHolder();
-
-        final String context = 
holder.getIdentifier().toClassAndNameIdentityString();
-        translateName(holder, context);
-        translateDescription(holder, context);
-    }
-
-    // //////////////////////////////////////
-
-    void translateName(final IdentifiedHolder facetHolder, final String 
context) {
-        final NamedFacet facet = facetHolder.getFacet(NamedFacet.class);
-        if(facet == null) {
-            // not expected...
-            return;
-        }
-        final String originalText = facet.value();
-        if (isNullOrEmptyWhenTrimmed(originalText)) {
-            // not expected...
-            return;
-        }
-
-        final TranslationService translationService = 
lookupTranslationService();
-        final LocaleProvider localeProvider = lookupLocaleProvider();
-
-        if(translationService != null && localeProvider != null) {
-            FacetUtil.addFacet(new NamedFacetTranslated(context, originalText, 
translationService, facetHolder));
-        }
-    }
-
-    void translateDescription(final FacetHolder facetHolder, final String 
context) {
-
-        final IdentifiedHolder holder = (IdentifiedHolder) facetHolder;
-        final DescribedAsFacet facet = 
facetHolder.getFacet(DescribedAsFacet.class);
-        if(facet == null) {
-            return;
-        }
-        final String originalText = facet.value();
-        if (isNullOrEmptyWhenTrimmed(originalText)) {
-            return;
-        }
-
-        final TranslationService translationService = 
lookupTranslationService();
-        final LocaleProvider localeProvider = lookupLocaleProvider();
-
-        if(translationService != null && localeProvider != null) {
-            FacetUtil.addFacet(new DescribedAsFacetTranslated(context, 
originalText, translationService, holder));
-        }
-
-    }
-
-    private boolean isNullOrEmptyWhenTrimmed(final String originalText) {
-        return originalText == null || 
Strings.isNullOrEmpty(originalText.trim());
-    }
-
-    // //////////////////////////////////////
-
-    /**
-     * Looks up from {@link 
org.apache.isis.core.metamodel.runtimecontext.ServicesInjector}, otherwise 
defaults to
-     * {@link 
org.apache.isis.core.metamodel.services.i18n.LocaleProviderDefault}.
-     */
-    LocaleProvider lookupLocaleProvider() {
-        if(localeProvider == null) {
-            localeProvider = 
servicesInjector.lookupService(LocaleProvider.class);
-        }
-        return localeProvider;
-    }
-
-    /**
-     * Looks up from {@link 
org.apache.isis.core.metamodel.runtimecontext.ServicesInjector}, otherwise 
defaults to
-     * {@link 
org.apache.isis.core.metamodel.services.i18n.po.TranslationServicePo}.
-     */
-    TranslationService lookupTranslationService() {
-        if(translationService == null) {
-            translationService = 
servicesInjector.lookupService(TranslationService.class);
-        }
-        return translationService;
-    }
-
-    @Override
-    public void setServicesInjector(final ServicesInjector servicesInjector) {
-        this.servicesInjector = servicesInjector;
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/3f5fbc44/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/i18n/TranslationFacetFactory.java
----------------------------------------------------------------------
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/i18n/TranslationFacetFactory.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/i18n/TranslationFacetFactory.java
new file mode 100644
index 0000000..9dc4e36
--- /dev/null
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/i18n/TranslationFacetFactory.java
@@ -0,0 +1,160 @@
+/*
+ *  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.all.i18n;
+
+
+import com.google.common.base.Strings;
+import org.apache.isis.applib.services.i18n.LocaleProvider;
+import org.apache.isis.applib.services.i18n.TranslationService;
+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.facetapi.IdentifiedHolder;
+import org.apache.isis.core.metamodel.facets.ContributeeMemberFacetFactory;
+import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
+import org.apache.isis.core.metamodel.facets.all.describedas.DescribedAsFacet;
+import org.apache.isis.core.metamodel.facets.all.named.NamedFacet;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjector;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjectorAware;
+
+public class TranslationFacetFactory extends FacetFactoryAbstract implements 
ContributeeMemberFacetFactory, ServicesInjectorAware {
+
+    private ServicesInjector servicesInjector;
+
+    private TranslationService translationService;
+    private LocaleProvider localeProvider;
+
+    public TranslationFacetFactory() {
+        super(FeatureType.EVERYTHING);
+    }
+
+    @Override
+    public void process(final ProcessClassContext processClassContext) {
+        final FacetHolder facetHolder = processClassContext.getFacetHolder();
+        if(facetHolder instanceof IdentifiedHolder) {
+            final IdentifiedHolder holder = (IdentifiedHolder) facetHolder;
+            final String context = 
holder.getIdentifier().toClassIdentityString();
+            translateName(holder, context);
+            translateDescription(holder, context);
+        }
+    }
+
+    @Override
+    public void process(final ProcessMethodContext processMethodContext) {
+        final IdentifiedHolder holder = processMethodContext.getFacetHolder();
+
+        final String context = 
holder.getIdentifier().toClassAndNameIdentityString();
+        translateName(holder, context);
+        translateDescription(holder, context);
+    }
+
+    @Override
+    public void processParams(final ProcessParameterContext 
processParameterContext) {
+        final IdentifiedHolder holder = 
processParameterContext.getFacetHolder();
+
+        final String context = holder.getIdentifier().toFullIdentityString();
+        translateName(holder, context);
+        translateDescription(holder, context);
+    }
+
+    @Override
+    public void process(final ProcessContributeeMemberContext 
processMemberContext) {
+        final IdentifiedHolder holder = processMemberContext.getFacetHolder();
+
+        final String context = 
holder.getIdentifier().toClassAndNameIdentityString();
+        translateName(holder, context);
+        translateDescription(holder, context);
+    }
+
+    // //////////////////////////////////////
+
+    void translateName(final IdentifiedHolder facetHolder, final String 
context) {
+        final NamedFacet facet = facetHolder.getFacet(NamedFacet.class);
+        if(facet == null) {
+            // not expected...
+            return;
+        }
+        final String originalText = facet.value();
+        if (isNullOrEmptyWhenTrimmed(originalText)) {
+            // not expected...
+            return;
+        }
+
+        final TranslationService translationService = 
lookupTranslationService();
+        final LocaleProvider localeProvider = lookupLocaleProvider();
+
+        if(translationService != null && localeProvider != null) {
+            FacetUtil.addFacet(new NamedFacetTranslated(context, originalText, 
translationService, facetHolder));
+        }
+    }
+
+    void translateDescription(final FacetHolder facetHolder, final String 
context) {
+
+        final IdentifiedHolder holder = (IdentifiedHolder) facetHolder;
+        final DescribedAsFacet facet = 
facetHolder.getFacet(DescribedAsFacet.class);
+        if(facet == null) {
+            return;
+        }
+        final String originalText = facet.value();
+        if (isNullOrEmptyWhenTrimmed(originalText)) {
+            return;
+        }
+
+        final TranslationService translationService = 
lookupTranslationService();
+        final LocaleProvider localeProvider = lookupLocaleProvider();
+
+        if(translationService != null && localeProvider != null) {
+            FacetUtil.addFacet(new DescribedAsFacetTranslated(context, 
originalText, translationService, holder));
+        }
+
+    }
+
+    private boolean isNullOrEmptyWhenTrimmed(final String originalText) {
+        return originalText == null || 
Strings.isNullOrEmpty(originalText.trim());
+    }
+
+    // //////////////////////////////////////
+
+    /**
+     * Looks up from {@link 
org.apache.isis.core.metamodel.runtimecontext.ServicesInjector}, otherwise 
defaults to
+     * {@link 
org.apache.isis.core.metamodel.services.i18n.LocaleProviderDefault}.
+     */
+    LocaleProvider lookupLocaleProvider() {
+        if(localeProvider == null) {
+            localeProvider = 
servicesInjector.lookupService(LocaleProvider.class);
+        }
+        return localeProvider;
+    }
+
+    /**
+     * Looks up from {@link 
org.apache.isis.core.metamodel.runtimecontext.ServicesInjector}, otherwise 
defaults to
+     * {@link 
org.apache.isis.core.metamodel.services.i18n.po.TranslationServicePo}.
+     */
+    TranslationService lookupTranslationService() {
+        if(translationService == null) {
+            translationService = 
servicesInjector.lookupService(TranslationService.class);
+        }
+        return translationService;
+    }
+
+    @Override
+    public void setServicesInjector(final ServicesInjector servicesInjector) {
+        this.servicesInjector = servicesInjector;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/3f5fbc44/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionAddToRemoveFromAndValidateFacetFactory.java
----------------------------------------------------------------------
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionAddToRemoveFromAndValidateFacetFactory.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionAddToRemoveFromAndValidateFacetFactory.java
index 5184e9d..8695718 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionAddToRemoveFromAndValidateFacetFactory.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionAddToRemoveFromAndValidateFacetFactory.java
@@ -20,7 +20,8 @@
 package org.apache.isis.core.metamodel.facets.collections.modify;
 
 import java.lang.reflect.Method;
-
+import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.core.commons.lang.StringExtensions;
 import org.apache.isis.core.metamodel.adapter.ObjectDirtier;
 import org.apache.isis.core.metamodel.adapter.ObjectDirtierAware;
@@ -28,24 +29,26 @@ import 
org.apache.isis.core.metamodel.exceptions.MetaModelException;
 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.facetapi.IdentifiedHolder;
 import org.apache.isis.core.metamodel.facets.FacetFactory;
-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;
 import 
org.apache.isis.core.metamodel.facets.collections.validate.CollectionValidateAddToFacetViaMethod;
 import 
org.apache.isis.core.metamodel.facets.collections.validate.CollectionValidateRemoveFromFacetViaMethod;
+import org.apache.isis.core.metamodel.methodutils.MethodScope;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjector;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjectorAware;
 
 /**
  * TODO: should probably split out into two {@link FacetFactory}s, one for
  * <tt>addTo()</tt>/<tt>removeFrom()</tt> and one for <tt>validateAddTo()</tt>/
  * <tt>validateRemoveFrom()</tt>.
  */
-public class CollectionAddToRemoveFromAndValidateFacetFactory extends 
MethodPrefixBasedFacetFactoryAbstract implements ObjectDirtierAware {
+public class CollectionAddToRemoveFromAndValidateFacetFactory extends 
MethodPrefixBasedFacetFactoryAbstract implements ObjectDirtierAware, 
ServicesInjectorAware {
 
     private static final String[] PREFIXES = {};
 
-    private ObjectDirtier objectDirtier;
 
     public CollectionAddToRemoveFromAndValidateFacetFactory() {
         super(FeatureType.COLLECTIONS_ONLY, OrphanValidation.VALIDATE, 
PREFIXES);
@@ -134,17 +137,30 @@ public class 
CollectionAddToRemoveFromAndValidateFacetFactory extends MethodPref
 
         final Class<?> cls = processMethodContext.getCls();
         final Class<?>[] paramTypes = 
MethodFinderUtils.paramTypesOrNull(collectionType);
-        Method validateAddToMethod = MethodFinderUtils.findMethod(cls, 
MethodScope.OBJECT, MethodPrefixConstants.VALIDATE_ADD_TO_PREFIX + 
capitalizedName, String.class, paramTypes);
+        Method validateAddToMethod = MethodFinderUtils.findMethod(
+                cls, MethodScope.OBJECT,
+                MethodPrefixConstants.VALIDATE_ADD_TO_PREFIX + capitalizedName,
+                new Class<?>[]{String.class, TranslatableString.class},
+                paramTypes);
         if (validateAddToMethod == null) {
-            validateAddToMethod = MethodFinderUtils.findMethod(cls, 
MethodScope.OBJECT, MethodPrefixConstants.VALIDATE_ADD_TO_PREFIX_2 + 
capitalizedName, String.class, 
MethodFinderUtils.paramTypesOrNull(collectionType));
+            validateAddToMethod = MethodFinderUtils.findMethod(
+                    cls, MethodScope.OBJECT,
+                    MethodPrefixConstants.VALIDATE_ADD_TO_PREFIX_2 + 
capitalizedName,
+                    new Class<?>[]{String.class, TranslatableString.class},
+                    MethodFinderUtils.paramTypesOrNull(collectionType));
         }
         if (validateAddToMethod == null) {
             return;
         }
         processMethodContext.removeMethod(validateAddToMethod);
 
-        final FacetHolder collection = processMethodContext.getFacetHolder();
-        FacetUtil.addFacet(new 
CollectionValidateAddToFacetViaMethod(validateAddToMethod, collection));
+        final IdentifiedHolder facetHolder = 
processMethodContext.getFacetHolder();
+        final TranslationService translationService = 
servicesInjector.lookupService(TranslationService.class);
+        // sadness: same as in TranslationFactory
+        final String translationContext = 
facetHolder.getIdentifier().toClassAndNameIdentityString();
+
+        final CollectionValidateAddToFacetViaMethod facet = new 
CollectionValidateAddToFacetViaMethod(validateAddToMethod, translationService, 
translationContext, facetHolder);
+        FacetUtil.addFacet(facet);
     }
 
     private void 
attachValidateRemoveFacetIfValidateRemoveFromMethodIsFound(final 
ProcessMethodContext processMethodContext, final Class<?> collectionType) {
@@ -154,23 +170,37 @@ public class 
CollectionAddToRemoveFromAndValidateFacetFactory extends MethodPref
 
         final Class<?> cls = processMethodContext.getCls();
         final Class<?>[] paramTypes = 
MethodFinderUtils.paramTypesOrNull(collectionType);
-        Method validateRemoveFromMethod = MethodFinderUtils.findMethod(cls, 
MethodScope.OBJECT, MethodPrefixConstants.VALIDATE_REMOVE_FROM_PREFIX + 
capitalizedName, String.class, paramTypes);
+        Method validateRemoveFromMethod = MethodFinderUtils.findMethod(
+                cls, MethodScope.OBJECT,
+                MethodPrefixConstants.VALIDATE_REMOVE_FROM_PREFIX + 
capitalizedName,
+                new Class<?>[]{String.class, TranslatableString.class},
+                paramTypes);
         if (validateRemoveFromMethod == null) {
-            validateRemoveFromMethod = MethodFinderUtils.findMethod(cls, 
MethodScope.OBJECT, MethodPrefixConstants.VALIDATE_REMOVE_FROM_PREFIX_2 + 
capitalizedName, String.class, 
MethodFinderUtils.paramTypesOrNull(collectionType));
+            validateRemoveFromMethod = MethodFinderUtils.findMethod(
+                    cls, MethodScope.OBJECT,
+                    MethodPrefixConstants.VALIDATE_REMOVE_FROM_PREFIX_2 + 
capitalizedName,
+                    new Class<?>[]{String.class, TranslatableString.class},
+                    MethodFinderUtils.paramTypesOrNull(collectionType));
         }
         if (validateRemoveFromMethod == null) {
             return;
         }
         processMethodContext.removeMethod(validateRemoveFromMethod);
 
-        final FacetHolder collection = processMethodContext.getFacetHolder();
-        FacetUtil.addFacet(new 
CollectionValidateRemoveFromFacetViaMethod(validateRemoveFromMethod, 
collection));
+        final IdentifiedHolder facetHolder = 
processMethodContext.getFacetHolder();
+        final TranslationService translationService = 
servicesInjector.lookupService(TranslationService.class);
+        // sadness: same as in TranslationFactory
+        final String translationContext = 
facetHolder.getIdentifier().toClassAndNameIdentityString();
+
+        final CollectionValidateRemoveFromFacetViaMethod facet = new 
CollectionValidateRemoveFromFacetViaMethod(validateRemoveFromMethod, 
translationService, translationContext, facetHolder);
+        FacetUtil.addFacet(facet);
     }
 
     // ///////////////////////////////////////////////////////
     // Dependencies (injected)
     // ///////////////////////////////////////////////////////
 
+    private ObjectDirtier objectDirtier;
     protected ObjectDirtier getObjectDirtier() {
         return objectDirtier;
     }
@@ -180,4 +210,9 @@ public class 
CollectionAddToRemoveFromAndValidateFacetFactory extends MethodPref
         this.objectDirtier = objectDirtier;
     }
 
+    private ServicesInjector servicesInjector;
+    @Override
+    public void setServicesInjector(final ServicesInjector servicesInjector) {
+        this.servicesInjector = servicesInjector;
+    }
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/3f5fbc44/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateAddToFacetViaMethod.java
----------------------------------------------------------------------
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateAddToFacetViaMethod.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateAddToFacetViaMethod.java
index 934cb3e..609251f 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateAddToFacetViaMethod.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateAddToFacetViaMethod.java
@@ -23,6 +23,8 @@ import java.lang.reflect.Method;
 import java.util.Collections;
 import java.util.List;
 
+import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.ImperativeFacet;
@@ -30,10 +32,14 @@ import 
org.apache.isis.core.metamodel.facets.ImperativeFacet;
 public class CollectionValidateAddToFacetViaMethod extends 
CollectionValidateAddToFacetAbstract implements ImperativeFacet {
 
     private final Method method;
+    private final TranslationService translationService;
+    private final String translationContext;
 
-    public CollectionValidateAddToFacetViaMethod(final Method method, final 
FacetHolder holder) {
+    public CollectionValidateAddToFacetViaMethod(final Method method, final 
TranslationService translationService, final String translationContext, final 
FacetHolder holder) {
         super(holder);
         this.method = method;
+        this.translationService = translationService;
+        this.translationContext = translationContext;
     }
 
     /**
@@ -62,7 +68,15 @@ public class CollectionValidateAddToFacetViaMethod extends 
CollectionValidateAdd
 
     @Override
     public String invalidReason(final ObjectAdapter owningAdapter, final 
ObjectAdapter proposedAdapter) {
-        return (String) ObjectAdapter.InvokeUtils.invoke(method, 
owningAdapter, proposedAdapter);
+        final Object returnValue = ObjectAdapter.InvokeUtils.invoke(method, 
owningAdapter, proposedAdapter);
+        if(returnValue instanceof String) {
+            return (String) returnValue;
+        }
+        if(returnValue instanceof TranslatableString) {
+            final TranslatableString ts = (TranslatableString) returnValue;
+            return ts.translate(translationService, translationContext);
+        }
+        return null;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/isis/blob/3f5fbc44/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateRemoveFromFacetViaMethod.java
----------------------------------------------------------------------
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateRemoveFromFacetViaMethod.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateRemoveFromFacetViaMethod.java
index 96a0409..c5881e0 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateRemoveFromFacetViaMethod.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateRemoveFromFacetViaMethod.java
@@ -23,6 +23,8 @@ import java.lang.reflect.Method;
 import java.util.Collections;
 import java.util.List;
 
+import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.ImperativeFacet;
@@ -30,10 +32,14 @@ import 
org.apache.isis.core.metamodel.facets.ImperativeFacet;
 public class CollectionValidateRemoveFromFacetViaMethod extends 
CollectionValidateRemoveFromFacetAbstract implements ImperativeFacet {
 
     private final Method method;
+    private final TranslationService translationService;
+    private final String translationContext;
 
-    public CollectionValidateRemoveFromFacetViaMethod(final Method method, 
final FacetHolder holder) {
+    public CollectionValidateRemoveFromFacetViaMethod(final Method method, 
final TranslationService translationService, final String translationContext, 
final FacetHolder holder) {
         super(holder);
         this.method = method;
+        this.translationService = translationService;
+        this.translationContext = translationContext;
     }
 
     /**
@@ -62,7 +68,15 @@ public class CollectionValidateRemoveFromFacetViaMethod 
extends CollectionValida
 
     @Override
     public String invalidReason(final ObjectAdapter owningAdapter, final 
ObjectAdapter proposedAdapter) {
-        return (String) ObjectAdapter.InvokeUtils.invoke(method, 
owningAdapter, proposedAdapter);
+        final Object returnValue = ObjectAdapter.InvokeUtils.invoke(method, 
owningAdapter, proposedAdapter);
+        if(returnValue instanceof String) {
+            return (String) returnValue;
+        }
+        if(returnValue instanceof TranslatableString) {
+            final TranslatableString ts = (TranslatableString) returnValue;
+            return ts.translate(translationService, translationContext);
+        }
+        return null;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/isis/blob/3f5fbc44/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethod.java
----------------------------------------------------------------------
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethod.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethod.java
index 3d1749c..6bd38bf 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethod.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethod.java
@@ -24,6 +24,8 @@ import java.util.Collections;
 import java.util.List;
 
 import org.apache.isis.applib.events.UsabilityEvent;
+import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.ImperativeFacet;
@@ -32,10 +34,17 @@ import 
org.apache.isis.core.metamodel.interactions.UsabilityContext;
 public class DisableForContextFacetViaMethod extends 
DisableForContextFacetAbstract implements ImperativeFacet {
 
     private final Method method;
+    private final TranslationService translationService;
+    private final String translationContext;
 
-    public DisableForContextFacetViaMethod(final Method method, final 
FacetHolder holder) {
+    public DisableForContextFacetViaMethod(
+            final Method method,
+            final TranslationService translationService, final String 
translationContext,
+            final FacetHolder holder) {
         super(holder);
         this.method = method;
+        this.translationService = translationService;
+        this.translationContext = translationContext;
     }
 
     /**
@@ -71,7 +80,15 @@ public class DisableForContextFacetViaMethod extends 
DisableForContextFacetAbstr
         if (target == null) {
             return null;
         }
-        return (String) ObjectAdapter.InvokeUtils.invoke(method, target, 
ic.getContributeeAsMap());
+        final Object returnValue = ObjectAdapter.InvokeUtils.invoke(method, 
target, ic.getContributeeAsMap());
+        if(returnValue instanceof String) {
+            return (String) returnValue;
+        }
+        if(returnValue instanceof TranslatableString) {
+            final TranslatableString ts = (TranslatableString) returnValue;
+            return ts.translate(translationService, translationContext);
+        }
+        return null;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/isis/blob/3f5fbc44/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethodFactory.java
----------------------------------------------------------------------
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethodFactory.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethodFactory.java
index 79a6d1a..a0f036c 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethodFactory.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethodFactory.java
@@ -20,18 +20,22 @@
 package org.apache.isis.core.metamodel.facets.members.disabled.method;
 
 import java.lang.reflect.Method;
-
+import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.core.commons.lang.StringExtensions;
 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.methodutils.MethodScope;
+import org.apache.isis.core.metamodel.facetapi.IdentifiedHolder;
 import org.apache.isis.core.metamodel.facets.MethodFinderUtils;
 import 
org.apache.isis.core.metamodel.facets.MethodPrefixBasedFacetFactoryAbstract;
 import org.apache.isis.core.metamodel.facets.MethodPrefixConstants;
+import org.apache.isis.core.metamodel.methodutils.MethodScope;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjector;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjectorAware;
 
-public class DisableForContextFacetViaMethodFactory extends 
MethodPrefixBasedFacetFactoryAbstract {
+public class DisableForContextFacetViaMethodFactory extends 
MethodPrefixBasedFacetFactoryAbstract implements ServicesInjectorAware {
 
     private static final String[] PREFIXES = { 
MethodPrefixConstants.DISABLE_PREFIX };
 
@@ -52,13 +56,17 @@ public class DisableForContextFacetViaMethodFactory extends 
MethodPrefixBasedFac
         attachDisabledFacetIfDisabledMethodIsFound(processMethodContext);
     }
 
-    public static void attachDisabledFacetIfDisabledMethodIsFound(final 
ProcessMethodContext processMethodContext) {
+    private void attachDisabledFacetIfDisabledMethodIsFound(final 
ProcessMethodContext processMethodContext) {
 
         final Method method = processMethodContext.getMethod();
         final String capitalizedName = 
StringExtensions.asJavaBaseNameStripAccessorPrefixIfRequired(method.getName());
 
         final Class<?> cls = processMethodContext.getCls();
-        final Method disableMethod = MethodFinderUtils.findMethod(cls, 
MethodScope.OBJECT, MethodPrefixConstants.DISABLE_PREFIX + capitalizedName, 
String.class, method.getParameterTypes());
+        Method disableMethod = MethodFinderUtils.findMethod(
+                cls, MethodScope.OBJECT,
+                MethodPrefixConstants.DISABLE_PREFIX + capitalizedName,
+                new Class<?>[]{String.class, TranslatableString.class},
+                method.getParameterTypes());
         if (disableMethod == null) {
             return;
         }
@@ -66,7 +74,16 @@ public class DisableForContextFacetViaMethodFactory extends 
MethodPrefixBasedFac
         processMethodContext.removeMethod(disableMethod);
 
         final FacetHolder facetHolder = processMethodContext.getFacetHolder();
-        FacetUtil.addFacet(new DisableForContextFacetViaMethod(disableMethod, 
facetHolder));
+        final TranslationService translationService = 
this.servicesInjector.lookupService(TranslationService.class);
+        // sadness: same logic as in I18nFacetFactory
+        final String translationContext = 
((IdentifiedHolder)facetHolder).getIdentifier().toClassAndNameIdentityString();
+        FacetUtil.addFacet(new DisableForContextFacetViaMethod(disableMethod, 
translationService, translationContext, facetHolder));
     }
 
+    private ServicesInjector servicesInjector;
+
+    @Override
+    public void setServicesInjector(final ServicesInjector servicesInjector) {
+        this.servicesInjector = servicesInjector;
+    }
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/3f5fbc44/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/disabled/method/DisabledObjectFacetViaMethod.java
----------------------------------------------------------------------
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/disabled/method/DisabledObjectFacetViaMethod.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/disabled/method/DisabledObjectFacetViaMethod.java
index a1533e3..8d2bc5f 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/disabled/method/DisabledObjectFacetViaMethod.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/disabled/method/DisabledObjectFacetViaMethod.java
@@ -25,6 +25,8 @@ import java.util.List;
 
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.Identifier.Type;
+import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facetapi.FacetUtil;
@@ -34,10 +36,18 @@ import 
org.apache.isis.core.metamodel.facets.object.disabled.DisabledObjectFacet
 public class DisabledObjectFacetViaMethod extends DisabledObjectFacetAbstract 
implements ImperativeFacet {
 
     private final Method method;
+    private TranslationService translationService;
+    private final String translationContext;
 
-    public DisabledObjectFacetViaMethod(final Method method, final FacetHolder 
holder) {
+    public DisabledObjectFacetViaMethod(
+            final Method method,
+            final TranslationService translationService,
+            final String translationContext,
+            final FacetHolder holder) {
         super(holder);
         this.method = method;
+        this.translationService = translationService;
+        this.translationContext = translationContext;
     }
 
     @Override
@@ -62,9 +72,16 @@ public class DisabledObjectFacetViaMethod extends 
DisabledObjectFacetAbstract im
 
     @Override
     public String disabledReason(final ObjectAdapter owningAdapter, final 
Identifier identifier) {
-        // String type = identifier.getType().toString();
         final Type type = identifier.getType();
-        return (String) ObjectAdapter.InvokeUtils.invoke(method, 
owningAdapter, type);
+        final Object returnValue = ObjectAdapter.InvokeUtils.invoke(method, 
owningAdapter, type);
+        if(returnValue instanceof String) {
+            return (String) returnValue;
+        }
+        if(returnValue instanceof TranslatableString) {
+            final TranslatableString ts = (TranslatableString) returnValue;
+            return ts.translate(translationService, translationContext);
+        }
+        return null;
     }
 
     @Override
@@ -74,7 +91,7 @@ public class DisabledObjectFacetViaMethod extends 
DisabledObjectFacetAbstract im
 
     @Override
     public void copyOnto(final FacetHolder holder) {
-        final DisabledObjectFacetViaMethod clonedFacet = new 
DisabledObjectFacetViaMethod(this.method, holder);
+        final DisabledObjectFacetViaMethod clonedFacet = new 
DisabledObjectFacetViaMethod(this.method, translationService, 
translationContext, holder);
         FacetUtil.addFacet(clonedFacet);
     }
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/3f5fbc44/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/disabled/method/DisabledObjectFacetViaMethodFactory.java
----------------------------------------------------------------------
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/disabled/method/DisabledObjectFacetViaMethodFactory.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/disabled/method/DisabledObjectFacetViaMethodFactory.java
index e4fb165..e88efdd 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/disabled/method/DisabledObjectFacetViaMethodFactory.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/disabled/method/DisabledObjectFacetViaMethodFactory.java
@@ -20,18 +20,22 @@
 package org.apache.isis.core.metamodel.facets.object.disabled.method;
 
 import java.lang.reflect.Method;
-
 import org.apache.isis.applib.Identifier;
+import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationService;
 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.facetapi.IdentifiedHolder;
 import org.apache.isis.core.metamodel.facets.FacetedMethod;
-import org.apache.isis.core.metamodel.methodutils.MethodScope;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
 import org.apache.isis.core.metamodel.facets.MethodFinderUtils;
 import 
org.apache.isis.core.metamodel.facets.MethodPrefixBasedFacetFactoryAbstract;
 import 
org.apache.isis.core.metamodel.facets.object.disabled.DisabledObjectFacet;
+import org.apache.isis.core.metamodel.methodutils.MethodScope;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjector;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjectorAware;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
 
 /**
  * Installs the {@link DisabledObjectFacetViaMethod} on the
@@ -44,11 +48,12 @@ import 
org.apache.isis.core.metamodel.facets.object.disabled.DisabledObjectFacet
  * class is being processed}, the {@link ObjectMember member}s for the
  * {@link ObjectSpecification spec} are not known.
  */
-public class DisabledObjectFacetViaMethodFactory extends 
MethodPrefixBasedFacetFactoryAbstract {
+public class DisabledObjectFacetViaMethodFactory extends 
MethodPrefixBasedFacetFactoryAbstract implements ServicesInjectorAware {
 
     private static final String DISABLED_PREFIX = "disabled";
 
     private static final String[] PREFIXES = { DISABLED_PREFIX, };
+    private ServicesInjector servicesInjector;
 
     public DisabledObjectFacetViaMethodFactory() {
         super(FeatureType.EVERYTHING_BUT_PARAMETERS, 
OrphanValidation.VALIDATE, PREFIXES);
@@ -58,14 +63,22 @@ public class DisabledObjectFacetViaMethodFactory extends 
MethodPrefixBasedFacetF
     public void process(final ProcessClassContext processClassContext) {
         final Class<?> cls = processClassContext.getCls();
         final FacetHolder facetHolder = processClassContext.getFacetHolder();
-        final Class<?>[] params = new Class<?>[1];
-        params[0] = Identifier.Type.class;// String.class;
+        final Class<?>[] paramTypes = new Class<?>[1];
+        paramTypes[0] = Identifier.Type.class;// String.class;
 
-        final Method method = MethodFinderUtils.findMethod(cls, 
MethodScope.OBJECT, DISABLED_PREFIX, String.class, params);
+        final Method method = MethodFinderUtils.findMethod(
+                cls, MethodScope.OBJECT, DISABLED_PREFIX,
+                new Class<?>[]{String.class, TranslatableString.class},
+                paramTypes);
         if (method == null) {
             return;
         }
-        FacetUtil.addFacet(new DisabledObjectFacetViaMethod(method, 
facetHolder));
+
+        final TranslationService translationService = 
servicesInjector.lookupService(TranslationService.class);
+        // sadness: same logic as in I18nFacetFactory
+        final String translationContext = 
((IdentifiedHolder)facetHolder).getIdentifier().toClassIdentityString();
+        FacetUtil.addFacet(new DisabledObjectFacetViaMethod(method, 
translationService, translationContext, facetHolder));
+
         processClassContext.removeMethod(method);
     }
 
@@ -80,4 +93,8 @@ public class DisabledObjectFacetViaMethodFactory extends 
MethodPrefixBasedFacetF
         }
     }
 
+    @Override
+    public void setServicesInjector(final ServicesInjector servicesInjector) {
+        this.servicesInjector = servicesInjector;
+    }
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/3f5fbc44/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/title/methods/TitleFacetViaMethodsFactory.java
----------------------------------------------------------------------
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/title/methods/TitleFacetViaMethodsFactory.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/title/methods/TitleFacetViaMethodsFactory.java
index 376960b..df86510 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/title/methods/TitleFacetViaMethodsFactory.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/title/methods/TitleFacetViaMethodsFactory.java
@@ -21,6 +21,8 @@ package 
org.apache.isis.core.metamodel.facets.object.title.methods;
 
 import java.lang.reflect.Method;
 
+import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.core.commons.lang.ClassExtensions;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facetapi.FacetUtil;
@@ -30,8 +32,10 @@ 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.fallback.FallbackFacetFactory;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjector;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjectorAware;
 
-public class TitleFacetViaMethodsFactory extends 
MethodPrefixBasedFacetFactoryAbstract {
+public class TitleFacetViaMethodsFactory extends 
MethodPrefixBasedFacetFactoryAbstract implements ServicesInjectorAware {
 
     private static final String TO_STRING = "toString";
     private static final String TITLE = "title";
@@ -51,10 +55,19 @@ public class TitleFacetViaMethodsFactory extends 
MethodPrefixBasedFacetFactoryAb
         final Class<?> cls = processClassContext.getCls();
         final FacetHolder facetHolder = processClassContext.getFacetHolder();
 
-        Method method = MethodFinderUtils.findMethod(cls, MethodScope.OBJECT, 
TITLE, String.class, null);
+        Method method = MethodFinderUtils.findMethod(
+                cls, MethodScope.OBJECT,
+                TITLE,
+                new Class<?>[]{String.class, TranslatableString.class},
+                null);
         if (method != null) {
             processClassContext.removeMethod(method);
-            FacetUtil.addFacet(new TitleFacetViaTitleMethod(method, 
facetHolder));
+            final TranslationService translationService = 
servicesInjector.lookupService(TranslationService.class);
+            // sadness: same as in TranslationFactory
+            final String translationContext = 
method.getDeclaringClass().getName() + "#" + method.getName() + "()";
+
+            final TitleFacetViaTitleMethod facet = new 
TitleFacetViaTitleMethod(method, translationService, translationContext, 
facetHolder);
+            FacetUtil.addFacet(facet);
             return;
         }
 
@@ -79,4 +92,13 @@ public class TitleFacetViaMethodsFactory extends 
MethodPrefixBasedFacetFactoryAb
             return;
         }
     }
+
+    // //////////////////////////////////////
+
+    private ServicesInjector servicesInjector;
+
+    @Override
+    public void setServicesInjector(final ServicesInjector servicesInjector) {
+        this.servicesInjector = servicesInjector;
+    }
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/3f5fbc44/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/title/methods/TitleFacetViaTitleMethod.java
----------------------------------------------------------------------
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/title/methods/TitleFacetViaTitleMethod.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/title/methods/TitleFacetViaTitleMethod.java
index 6a2884e..26f9f98 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/title/methods/TitleFacetViaTitleMethod.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/title/methods/TitleFacetViaTitleMethod.java
@@ -27,6 +27,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.apache.isis.applib.profiles.Localization;
+import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.ImperativeFacet;
@@ -35,11 +37,16 @@ import 
org.apache.isis.core.metamodel.facets.object.title.TitleFacetAbstract;
 public class TitleFacetViaTitleMethod extends TitleFacetAbstract implements 
ImperativeFacet {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(TitleFacetViaTitleMethod.class);
+
     private final Method method;
+    private final TranslationService translationService;
+    private final String translationContext;
 
-    public TitleFacetViaTitleMethod(final Method method, final FacetHolder 
holder) {
+    public TitleFacetViaTitleMethod(final Method method, final 
TranslationService translationService, final String translationContext, final 
FacetHolder holder) {
         super(holder);
         this.method = method;
+        this.translationService = translationService;
+        this.translationContext = translationContext;
     }
 
     /**
@@ -69,11 +76,18 @@ public class TitleFacetViaTitleMethod extends 
TitleFacetAbstract implements Impe
     @Override
     public String title(final ObjectAdapter owningAdapter, final Localization 
localization) {
         try {
-            return (String) ObjectAdapter.InvokeUtils.invoke(method, 
owningAdapter);
+            final Object returnValue = 
ObjectAdapter.InvokeUtils.invoke(method, owningAdapter);
+            if(returnValue instanceof String) {
+                return (String) returnValue;
+            }
+            if(returnValue instanceof TranslatableString) {
+                final TranslatableString ts = (TranslatableString) returnValue;
+                return ts.translate(translationService, translationContext);
+            }
+            return null;
         } catch (final RuntimeException ex) {
             LOG.warn("title failure", ex);
             return "Failed Title";
         }
     }
-
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/3f5fbc44/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/validating/validateobject/method/ValidateObjectFacetMethod.java
----------------------------------------------------------------------
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/validating/validateobject/method/ValidateObjectFacetMethod.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/validating/validateobject/method/ValidateObjectFacetMethod.java
index 2bc57b1..e3cd1ef 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/validating/validateobject/method/ValidateObjectFacetMethod.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/validating/validateobject/method/ValidateObjectFacetMethod.java
@@ -23,6 +23,8 @@ import java.lang.reflect.Method;
 import java.util.Collections;
 import java.util.List;
 
+import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.ImperativeFacet;
@@ -31,10 +33,14 @@ import 
org.apache.isis.core.metamodel.facets.object.validating.validateobject.Va
 public class ValidateObjectFacetMethod extends ValidateObjectFacetAbstract 
implements ImperativeFacet {
 
     private final Method method;
+    private final TranslationService translationService;
+    private final String translationContext;
 
-    public ValidateObjectFacetMethod(final Method method, final FacetHolder 
holder) {
+    public ValidateObjectFacetMethod(final Method method, final 
TranslationService translationService, final String translationContext, final 
FacetHolder holder) {
         super(holder);
         this.method = method;
+        this.translationService = translationService;
+        this.translationContext = translationContext;
     }
 
     @Override
@@ -59,7 +65,15 @@ public class ValidateObjectFacetMethod extends 
ValidateObjectFacetAbstract imple
 
     @Override
     public String invalidReason(final ObjectAdapter owningAdapter) {
-        return (String) ObjectAdapter.InvokeUtils.invoke(method, 
owningAdapter);
+        final Object returnValue = ObjectAdapter.InvokeUtils.invoke(method, 
owningAdapter);
+        if(returnValue instanceof String) {
+            return (String) returnValue;
+        }
+        if(returnValue instanceof TranslatableString) {
+            final TranslatableString ts = (TranslatableString) returnValue;
+            return ts.translate(translationService, translationContext);
+        }
+        return null;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/isis/blob/3f5fbc44/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/validating/validateobject/method/ValidateObjectFacetMethodFactory.java
----------------------------------------------------------------------
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/validating/validateobject/method/ValidateObjectFacetMethodFactory.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/validating/validateobject/method/ValidateObjectFacetMethodFactory.java
index fe74ee3..26f58c1 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/validating/validateobject/method/ValidateObjectFacetMethodFactory.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/validating/validateobject/method/ValidateObjectFacetMethodFactory.java
@@ -21,14 +21,19 @@ package 
org.apache.isis.core.metamodel.facets.object.validating.validateobject.m
 
 import java.lang.reflect.Method;
 
+import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationService;
 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.facetapi.IdentifiedHolder;
 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.runtimecontext.ServicesInjector;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjectorAware;
 
-public class ValidateObjectFacetMethodFactory extends 
MethodPrefixBasedFacetFactoryAbstract {
+public class ValidateObjectFacetMethodFactory extends 
MethodPrefixBasedFacetFactoryAbstract implements ServicesInjectorAware {
 
     private static final String VALIDATE_PREFIX = "validate";
 
@@ -43,10 +48,23 @@ public class ValidateObjectFacetMethodFactory extends 
MethodPrefixBasedFacetFact
         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);
+        final Method method = MethodFinderUtils.findMethod(
+                cls, MethodScope.OBJECT,
+                VALIDATE_PREFIX,
+                new Class<?>[]{String.class, TranslatableString.class},
+                NO_PARAMETERS_TYPES);
         if (method != null) {
-            FacetUtil.addFacet(new ValidateObjectFacetMethod(method, 
facetHolder));
+            final TranslationService translationService = 
servicesInjector.lookupService(TranslationService.class);
+            // sadness: same as in TranslationFactory
+            final String translationContext = 
((IdentifiedHolder)facetHolder).getIdentifier().toClassIdentityString();
+            FacetUtil.addFacet(new ValidateObjectFacetMethod(method, 
translationService, translationContext, facetHolder));
             processClassContext.removeMethod(method);
         }
     }
+
+    private ServicesInjector servicesInjector;
+    @Override
+    public void setServicesInjector(final ServicesInjector servicesInjector) {
+        this.servicesInjector = servicesInjector;
+    }
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/3f5fbc44/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/method/PropertyAutoCompleteFacetMethodFactory.java
----------------------------------------------------------------------
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/method/PropertyAutoCompleteFacetMethodFactory.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/method/PropertyAutoCompleteFacetMethodFactory.java
index 8a2bee7..3f73199 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/method/PropertyAutoCompleteFacetMethodFactory.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/method/PropertyAutoCompleteFacetMethodFactory.java
@@ -55,7 +55,7 @@ public class PropertyAutoCompleteFacetMethodFactory extends 
MethodPrefixBasedFac
 
         final Class<?> cls = processMethodContext.getCls();
         final Class<?> returnType = getMethod.getReturnType();
-        final Method autoCompleteMethod = MethodFinderUtils.findMethod(cls, 
MethodScope.OBJECT, MethodPrefixConstants.AUTO_COMPLETE_PREFIX + 
capitalizedName, null, new Class[]{String.class});
+        final Method autoCompleteMethod = MethodFinderUtils.findMethod(cls, 
MethodScope.OBJECT, MethodPrefixConstants.AUTO_COMPLETE_PREFIX + 
capitalizedName, (Class<?>)null, new Class[]{String.class});
         if (autoCompleteMethod == null) {
             return;
         }

http://git-wip-us.apache.org/repos/asf/isis/blob/3f5fbc44/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/choices/method/PropertyChoicesFacetViaMethodFactory.java
----------------------------------------------------------------------
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/choices/method/PropertyChoicesFacetViaMethodFactory.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/choices/method/PropertyChoicesFacetViaMethodFactory.java
index 3fe0722..6947c83 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/choices/method/PropertyChoicesFacetViaMethodFactory.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/choices/method/PropertyChoicesFacetViaMethodFactory.java
@@ -55,7 +55,7 @@ public class PropertyChoicesFacetViaMethodFactory extends 
MethodPrefixBasedFacet
 
         final Class<?> cls = processMethodContext.getCls();
         final Class<?> returnType = getMethod.getReturnType();
-        final Method choicesMethod = MethodFinderUtils.findMethod(cls, 
MethodScope.OBJECT, MethodPrefixConstants.CHOICES_PREFIX + capitalizedName, 
null, NO_PARAMETERS_TYPES);
+        final Method choicesMethod = MethodFinderUtils.findMethod(cls, 
MethodScope.OBJECT, MethodPrefixConstants.CHOICES_PREFIX + capitalizedName, 
(Class<?>)null, NO_PARAMETERS_TYPES);
         if (choicesMethod == null) {
             return;
         }

http://git-wip-us.apache.org/repos/asf/isis/blob/3f5fbc44/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
index a3d7518..b106202 100644
--- 
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
@@ -23,6 +23,8 @@ import java.lang.reflect.Method;
 import java.util.Collections;
 import java.util.List;
 
+import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.ImperativeFacet;
@@ -31,10 +33,14 @@ import 
org.apache.isis.core.metamodel.facets.properties.validating.PropertyValid
 public class PropertyValidateFacetViaMethod extends 
PropertyValidateFacetAbstract implements ImperativeFacet {
 
     private final Method method;
+    private final TranslationService translationService;
+    private final String translationContext;
 
-    public PropertyValidateFacetViaMethod(final Method method, final 
FacetHolder holder) {
+    public PropertyValidateFacetViaMethod(final Method method, final 
TranslationService translationService, final String translationContext, final 
FacetHolder holder) {
         super(holder);
         this.method = method;
+        this.translationService = translationService;
+        this.translationContext = translationContext;
     }
 
     /**
@@ -63,7 +69,15 @@ public class PropertyValidateFacetViaMethod extends 
PropertyValidateFacetAbstrac
 
     @Override
     public String invalidReason(final ObjectAdapter owningAdapter, final 
ObjectAdapter proposedAdapter) {
-        return (String) ObjectAdapter.InvokeUtils.invoke(method, 
owningAdapter, proposedAdapter);
+        final Object returnValue = ObjectAdapter.InvokeUtils.invoke(method, 
owningAdapter, proposedAdapter);
+        if(returnValue instanceof String) {
+            return (String) returnValue;
+        }
+        if(returnValue instanceof TranslatableString) {
+            final TranslatableString ts = (TranslatableString) returnValue;
+            return ts.translate(translationService, translationContext);
+        }
+        return null;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/isis/blob/3f5fbc44/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
index 1c3a8bc..dda8815 100644
--- 
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
@@ -20,17 +20,20 @@
 package org.apache.isis.core.metamodel.facets.properties.validating.method;
 
 import java.lang.reflect.Method;
-
+import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationService;
 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.FacetedMethod;
 import org.apache.isis.core.metamodel.facets.MethodFinderUtils;
 import 
org.apache.isis.core.metamodel.facets.MethodPrefixBasedFacetFactoryAbstract;
 import org.apache.isis.core.metamodel.facets.MethodPrefixConstants;
+import org.apache.isis.core.metamodel.methodutils.MethodScope;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjector;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjectorAware;
 
-public class PropertyValidateFacetViaMethodFactory extends 
MethodPrefixBasedFacetFactoryAbstract {
+public class PropertyValidateFacetViaMethodFactory extends 
MethodPrefixBasedFacetFactoryAbstract implements ServicesInjectorAware {
 
     private static final String[] PREFIXES = { 
MethodPrefixConstants.VALIDATE_PREFIX };
 
@@ -53,14 +56,31 @@ public class PropertyValidateFacetViaMethodFactory extends 
MethodPrefixBasedFace
         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);
+        final Method method = MethodFinderUtils.findMethod(
+                cls, MethodScope.OBJECT,
+                MethodPrefixConstants.VALIDATE_PREFIX + capitalizedName,
+                new Class<?>[]{String.class, TranslatableString.class},
+                paramTypes);
         if (method == null) {
             return;
         }
         processMethodContext.removeMethod(method);
 
-        final FacetHolder property = processMethodContext.getFacetHolder();
-        FacetUtil.addFacet(new PropertyValidateFacetViaMethod(method, 
property));
+        final FacetedMethod facetHolder = 
processMethodContext.getFacetHolder();
+
+        final TranslationService translationService = 
servicesInjector.lookupService(TranslationService.class);
+        // sadness: same as in TranslationFactory
+        final String translationContext = 
facetHolder.getIdentifier().toClassAndNameIdentityString();
+        final PropertyValidateFacetViaMethod facet = new 
PropertyValidateFacetViaMethod(method, translationService, translationContext, 
facetHolder);
+        FacetUtil.addFacet(facet);
     }
 
+
+    private ServicesInjector servicesInjector;
+
+    @Override
+    public void setServicesInjector(final ServicesInjector servicesInjector) {
+
+        this.servicesInjector = servicesInjector;
+    }
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/3f5fbc44/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/PoReader.java
----------------------------------------------------------------------
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/PoReader.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/PoReader.java
index 702d0b6..19776bc 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/PoReader.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/PoReader.java
@@ -69,14 +69,12 @@ class PoReader extends PoAbstract {
     //endregion
 
     public String translate(final String context, final String msgId) {
-        final Locale locale = 
translationServicePo.getLocaleProvider().getLocale();
-        return translate(context, msgId, ContextAndMsgId.Type.REGULAR, locale);
+        return translate(context, msgId, ContextAndMsgId.Type.REGULAR);
     }
 
     @Override
     String translate(final String context, final String msgId, final String 
msgIdPlural, final int num) {
 
-        final Locale locale = 
translationServicePo.getLocaleProvider().getLocale();
         final String msgIdToUse;
         final ContextAndMsgId.Type type;
         if (num == 1) {
@@ -87,12 +85,20 @@ class PoReader extends PoAbstract {
             type = ContextAndMsgId.Type.PLURAL_ONLY;
         }
 
-        return translate(context, msgIdToUse, type, locale);
+        return translate(context, msgIdToUse, type);
     }
 
     private String translate(
-            final String context, final String msgId, final 
ContextAndMsgId.Type type,
-            final Locale targetLocale) {
+            final String context, final String msgId, final 
ContextAndMsgId.Type type) {
+
+        final Locale targetLocale;
+        try {
+            targetLocale = 
translationServicePo.getLocaleProvider().getLocale();
+        } catch(final RuntimeException ex){
+            LOG.warn("Failed to obtain locale, returning the original msgId");
+            return msgId;
+        }
+
         final Map<ContextAndMsgId, String> translationsByKey = 
readAndCacheTranslationsIfRequired(targetLocale);
 
         final ContextAndMsgId key = new ContextAndMsgId(context, msgId, type);

http://git-wip-us.apache.org/repos/asf/isis/blob/3f5fbc44/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/PoWriter.java
----------------------------------------------------------------------
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/PoWriter.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/PoWriter.java
index b8d76df..6ff8117 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/PoWriter.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/PoWriter.java
@@ -71,7 +71,7 @@ class PoWriter extends PoAbstract {
         buf.append("\n# If the app uses TranslatableString (eg for 
internationalized validation");
         buf.append("\n# messages), or if the app calls the TranslationService 
directly, then ensure");
         buf.append("\n# that all text to be translated has been captured by 
running a full");
-        buf.append("\n# integration test suite that fully exercises all 
behaviour");
+        buf.append("\n# integration test suite that exercises all relevant 
behaviour");
         buf.append("\n#");
         
buf.append("\n##############################################################################");
         buf.append("\n");

http://git-wip-us.apache.org/repos/asf/isis/blob/3f5fbc44/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
----------------------------------------------------------------------
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
 
b/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
index 5a6e10c..1436377 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
@@ -34,7 +34,7 @@ import 
org.apache.isis.core.metamodel.facets.actions.notinservicemenu.annotation
 import 
org.apache.isis.core.metamodel.facets.actions.notinservicemenu.derived.NotInServiceMenuFacetDerivedFromDomainServiceFacetFactory;
 import 
org.apache.isis.core.metamodel.facets.actions.notinservicemenu.method.NotInServiceMenuFacetViaMethodFactory;
 import 
org.apache.isis.core.metamodel.facets.actions.validate.method.ActionValidationFacetViaMethodFactory;
-import org.apache.isis.core.metamodel.facets.all.i18n.I18nFacetFactory;
+import org.apache.isis.core.metamodel.facets.all.i18n.TranslationFacetFactory;
 import 
org.apache.isis.core.metamodel.facets.collections.accessor.CollectionAccessorFacetViaAccessorFactory;
 import 
org.apache.isis.core.metamodel.facets.collections.clear.CollectionClearFacetFactory;
 import 
org.apache.isis.core.metamodel.facets.collections.collection.CollectionAnnotationFacetFactory;
@@ -499,7 +499,7 @@ public final class ProgrammingModelFacetsJava5 extends 
ProgrammingModelAbstract
         addFactory(FacetsFacetAnnotationFactory.class);
 
         // must be after all named facets and description facets have been 
installed
-        addFactory(I18nFacetFactory.class);
+        addFactory(TranslationFacetFactory.class);
 
         addFactory(ViewModelSemanticCheckingFacetFactory.class);
     }

Reply via email to