You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jetspeed-dev@portals.apache.org by at...@apache.org on 2008/09/10 12:15:10 UTC

svn commit: r693769 - /portals/jetspeed-2/portal/branches/security-refactoring/jetspeed-api/src/main/java/org/apache/jetspeed/i18n/KeyedMessage.java

Author: ate
Date: Wed Sep 10 03:15:09 2008
New Revision: 693769

URL: http://svn.apache.org/viewvc?rev=693769&view=rev
Log:
Extended version of KeyedMessage to allow "scoping" messages to specific context use-case.
By using the new createScoped(...) methods, a scope infix for the ResourceBundle lookup key can be provided which will be evaluated first for finding a "scoped" version of the requested message.
For example: 

  SecurityException.PRINCIPAL_DOES_NOT_EXIST.createScoped("user", "foo")
  
will result in first lookup of a "user" scoped variant of the localized message using key:
    
    org.apache.jetspeed.security.SecurityException.user.PRINCIPAL_DOES_NOT_EXIST = The user {0} does not exist.

If that specific message is undefined (in any language for the resource bundle), the default lookup with commence, searching for:

    org.apache.jetspeed.security.SecurityException.PRINCIPAL_DOES_NOT_EXIST = The principal {0} does not exist.

This will allow us to define "generic" KeyedMessages for example for the new *extendable* JetspeedPrincipal security handling, for which we now can throw an exception like:

  throw new SecurityException.PRINCIPAL_DOES_NOT_EXIST.createScoped(jetspeedPrincipal.getPrincipalType().getName(),  jetspeedPrincipal.getName());

and have that automatically mapped and translated for the appropriate principal type "scope" (like in the example above).

NB: I've already added "some" javadoc on the new methods, but not yet documented this new feature on the class level (still TODO)  



Modified:
    portals/jetspeed-2/portal/branches/security-refactoring/jetspeed-api/src/main/java/org/apache/jetspeed/i18n/KeyedMessage.java

Modified: portals/jetspeed-2/portal/branches/security-refactoring/jetspeed-api/src/main/java/org/apache/jetspeed/i18n/KeyedMessage.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/security-refactoring/jetspeed-api/src/main/java/org/apache/jetspeed/i18n/KeyedMessage.java?rev=693769&r1=693768&r2=693769&view=diff
==============================================================================
--- portals/jetspeed-2/portal/branches/security-refactoring/jetspeed-api/src/main/java/org/apache/jetspeed/i18n/KeyedMessage.java (original)
+++ portals/jetspeed-2/portal/branches/security-refactoring/jetspeed-api/src/main/java/org/apache/jetspeed/i18n/KeyedMessage.java Wed Sep 10 03:15:09 2008
@@ -202,6 +202,8 @@
      * @see #getKey()
      */
     private String               key;
+    
+    private String               scopedKey;
 
     /**
      * Optional message format arguments which can only be set using a derived KeyedMessage using the
@@ -226,9 +228,14 @@
      * @param source the KeyedMessage to derive this instance from
      * @param arguments this instance specific message format arguments
      */
-    protected KeyedMessage(KeyedMessage source, Object[] arguments)
+    protected KeyedMessage(KeyedMessage source, String scope, Object[] arguments)
     {
         this.key = source.getKey();
+        if (scope != null)
+        {
+            int split = source.containingClass.getName().length()+1;
+            this.scopedKey = key.substring(0,split)+"."+scope+"."+key.substring(split);
+        }
         this.message = source.message;
         this.resolved = source.resolved;
         this.containingClass = source.containingClass;
@@ -365,7 +372,20 @@
      */
     protected KeyedMessage create(KeyedMessage source, Object[] arguments)
     {
-        return new KeyedMessage(this, arguments);
+        return new KeyedMessage(source, null, arguments);
+    }
+
+    /**
+     * Extendable scoped KeyedMessage factory
+     * 
+     * @param source the source to copy from
+     * @param scope the optional scope key infix between the containing class name and the field name
+     * @param arguments the optional message format arguments
+     * @return copied instance with new arguments set
+     */
+    protected KeyedMessage createScoped(KeyedMessage source, String scope, Object[] arguments)
+    {
+        return new KeyedMessage(source, scope, arguments);
     }
 
     /**
@@ -378,11 +398,28 @@
      */
     public KeyedMessage create(Object[] arguments)
     {
-        return new KeyedMessage(this, arguments);
+        return new KeyedMessage(this, null, arguments);
     }
 
     /**
-     * Simplied version of {@link #create(Object[])}with only one argument
+     * Creates a derived scoped KeyedMessage from this instance to provide additional message format arguments. <br/>
+     * The new instance will be {@link #equals(Object)}to this instance with only different arguments. <br/><br/>
+     * To allow reusing of the original KeyedMessage message format translatable not only by language but also for 
+     * specific contexts, this method allows providing a "scope" message key infix for lookup of a subset of the
+     * localized message specific for the specified "scope".
+     * Note: the argument objects should be lightweight types and preferably Serializable instances
+     * 
+     * @param scope the optional scope key infix between the containing class name and the field name
+     * @param arguments The derived instance specific message format arguments
+     * @return derived KeyedMessage {@link #equals(Object) equal}to this with its own message format arguments
+     */
+    public KeyedMessage createScoped(String scope, Object[] arguments)
+    {
+        return new KeyedMessage(this, scope, arguments);
+    }
+
+    /**
+     * Simplied version of {@link #create(Object[])}with only one message argument
      * 
      * @param single message format argument
      * @see #create(Object[])
@@ -394,6 +431,19 @@
     }
 
     /**
+     * Simplied version of {@link #createScoped(String, Object[])}with only one message argument
+     * 
+     * @param scope the optional scope key infix between the containing class name and the field name
+     * @param single message format argument
+     * @see #createScoped(String,Object[])
+     * @return derived KeyedMessage {@link #equals(Object) equal}to this with its own message format argument
+     */
+    public KeyedMessage createScoped(String scope, Object o)
+    {
+        return createScoped(scope, new Object[] { o });
+    }
+
+    /**
      * Simplied version of {@link #create(Object[])}with only two arguments
      * 
      * @param single message format argument
@@ -406,6 +456,19 @@
     }
 
     /**
+     * Simplied version of {@link #createScoped(String, Object[])}with only two arguments
+     * 
+     * @param scope the optional scope key infix between the containing class name and the field name
+     * @param single message format argument
+     * @see #createScoped(String,Object[])
+     * @return derived KeyedMessage {@link #equals(Object) equal}to this with its own message format arguments
+     */
+    public KeyedMessage createScoped(String scope, Object o1, Object o2)
+    {
+        return createScoped(scope, new Object[] { o1, o2 });
+    }
+
+    /**
      * Simplied version of {@link #create(Object[])}with only three arguments
      * 
      * @param single message format argument
@@ -418,6 +481,19 @@
     }
 
     /**
+     * Simplied version of {@link #createScoped(String, Object[])}with only three arguments
+     * 
+     * @param scope the optional scope key infix between the containing class name and the field name
+     * @param single message format argument
+     * @see #createScoped(String,Object[])
+     * @return derived KeyedMessage {@link #equals(Object) equal}to this with its own message format arguments
+     */
+    public KeyedMessage createScoped(String scope, Object o1, Object o2, Object o3)
+    {
+        return createScoped(scope, new Object[] { o1, o2, o3 });
+    }
+
+    /**
      * Dynamically derived key based on the definingClass name, postfixed with the static field name of this instance.
      * <br/><br/>Format: <br/><code>
      *     &nbsp;&nbsp;&lt;containingClass.name&gt;.&lt;staticInstanceField.name&gt;
@@ -489,6 +565,17 @@
         String message = this.message;
         if (resolved && bundle != null)
         {
+            if (scopedKey != null)
+            {
+                try
+                {
+                    message = bundle.getString(scopedKey);
+                }
+                catch (RuntimeException e)
+                {
+                    // ignore: fallback to default non-scoped message
+                }
+            }
             try
             {
                 message = bundle.getString(key);



---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org