Author: simoneg
Date: Fri Nov 20 03:33:15 2009
New Revision: 882400

URL: http://svn.apache.org/viewvc?rev=882400&view=rev
Log:
LABS-365 LABS-494 : moved context based settings to foundation-basice

Added:
    
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/MultipleSegmentContextElement.java
    
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/SingleSegmentContextElement.java
    
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/settings/ContextSettingsHolder.java
    labs/magma/trunk/foundation-basics/src/test/java/org/apache/magma/settings/
    
labs/magma/trunk/foundation-basics/src/test/java/org/apache/magma/settings/ContextSettingsHolderTest.java
    
labs/magma/trunk/foundation-basics/src/test/java/org/apache/magma/settings/PerformanceTest.java
Removed:
    
labs/magma/trunk/foundation-i18n/src/main/java/org/apache/magma/i18n/ContextMatrix.java
    
labs/magma/trunk/foundation-i18n/src/main/java/org/apache/magma/i18n/I18nContextElement.java
    
labs/magma/trunk/foundation-i18n/src/main/java/org/apache/magma/i18n/I18nContextElementsInstall.aj
    
labs/magma/trunk/foundation-i18n/src/main/java/org/apache/magma/i18n/I18nMultiSegmentContextElement.java
    
labs/magma/trunk/foundation-i18n/src/main/java/org/apache/magma/i18n/I18nSingleSegmentContextElement.java
    
labs/magma/trunk/foundation-i18n/src/test/java/org/apache/magma/i18n/LocaleHolderTest.java
    
labs/magma/trunk/foundation-i18n/src/test/java/org/apache/magma/i18n/MatchingTest.java
Modified:
    
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/ClassContextElement.java
    
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/MethodContextElement.java
    
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/StringContextElement.java
    
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/settings/SettingsHolder.java
    
labs/magma/trunk/foundation-i18n/src/main/java/org/apache/magma/i18n/LocaleHolder.java

Modified: 
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/ClassContextElement.java
URL: 
http://svn.apache.org/viewvc/labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/ClassContextElement.java?rev=882400&r1=882399&r2=882400&view=diff
==============================================================================
--- 
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/ClassContextElement.java
 (original)
+++ 
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/ClassContextElement.java
 Fri Nov 20 03:33:15 2009
@@ -21,9 +21,10 @@
  *
  * @author Simone Gianni <[email protected]>
  */
-public class ClassContextElement implements ContextElement {
+public class ClassContextElement implements ContextElement, 
SingleSegmentContextElement {
 
-       public Class<?> myclass = null;
+       protected Class<?> myclass = null;
+       protected String mytos = null;
        
        public ClassContextElement(Class<?> myclass) {
                this.myclass = myclass;
@@ -31,7 +32,9 @@
        
        @Override
        public String toString() {
-               return myclass.getSimpleName();
+               if (mytos == null)
+                       mytos = myclass.getSimpleName();
+               return mytos;
        }
        
        @Override
@@ -39,4 +42,8 @@
                if (!(obj instanceof ClassContextElement)) return false;
                return ((ClassContextElement)obj).myclass == myclass;
        }
+
+       public String getSegment() {
+               return toString();
+       }
 }

Modified: 
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/MethodContextElement.java
URL: 
http://svn.apache.org/viewvc/labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/MethodContextElement.java?rev=882400&r1=882399&r2=882400&view=diff
==============================================================================
--- 
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/MethodContextElement.java
 (original)
+++ 
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/MethodContextElement.java
 Fri Nov 20 03:33:15 2009
@@ -24,10 +24,11 @@
  *
  * @author Simone Gianni <[email protected]>
  */
-public class MethodContextElement implements ContextElement {
+public class MethodContextElement implements ContextElement, 
MultipleSegmentContextElement {
 
-       private Method method = null;
-       private Object[] args = null;
+       protected Method method = null;
+       protected Object[] args = null;
+       protected String[] mytos = null; 
        
        public MethodContextElement(Method method, Object[] args) {
                this.method = method;
@@ -56,5 +57,11 @@
        public Object[] getArgs() {
                return args;
        }
+
+       public String[] getSegments() {
+               if (mytos == null) 
+                       mytos = new String[] { 
method.getDeclaringClass().getSimpleName() , method.getName() };                
 
+               return mytos;
+       }
        
 }

Added: 
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/MultipleSegmentContextElement.java
URL: 
http://svn.apache.org/viewvc/labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/MultipleSegmentContextElement.java?rev=882400&view=auto
==============================================================================
--- 
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/MultipleSegmentContextElement.java
 (added)
+++ 
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/MultipleSegmentContextElement.java
 Fri Nov 20 03:33:15 2009
@@ -0,0 +1,7 @@
+package org.apache.magma.basics.context;
+
+public interface MultipleSegmentContextElement extends ContextElement {
+
+       public String[] getSegments();
+       
+}

Added: 
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/SingleSegmentContextElement.java
URL: 
http://svn.apache.org/viewvc/labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/SingleSegmentContextElement.java?rev=882400&view=auto
==============================================================================
--- 
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/SingleSegmentContextElement.java
 (added)
+++ 
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/SingleSegmentContextElement.java
 Fri Nov 20 03:33:15 2009
@@ -0,0 +1,7 @@
+package org.apache.magma.basics.context;
+
+public interface SingleSegmentContextElement extends ContextElement {
+       
+       public String getSegment();
+ 
+}

Modified: 
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/StringContextElement.java
URL: 
http://svn.apache.org/viewvc/labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/StringContextElement.java?rev=882400&r1=882399&r2=882400&view=diff
==============================================================================
--- 
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/StringContextElement.java
 (original)
+++ 
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/StringContextElement.java
 Fri Nov 20 03:33:15 2009
@@ -21,7 +21,7 @@
  *
  * @author Simone Gianni <[email protected]>
  */
-public class StringContextElement implements ContextElement {
+public class StringContextElement implements ContextElement, 
SingleSegmentContextElement {
 
        public CharSequence mystring = null;
        
@@ -39,5 +39,9 @@
                if (!(obj instanceof StringContextElement)) return false;
                return ((StringContextElement)obj).mystring.equals(mystring);
        }
+
+       public String getSegment() {
+               return toString();
+       }
        
 }

Added: 
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/settings/ContextSettingsHolder.java
URL: 
http://svn.apache.org/viewvc/labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/settings/ContextSettingsHolder.java?rev=882400&view=auto
==============================================================================
--- 
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/settings/ContextSettingsHolder.java
 (added)
+++ 
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/settings/ContextSettingsHolder.java
 Fri Nov 20 03:33:15 2009
@@ -0,0 +1,184 @@
+package org.apache.magma.settings;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+
+import org.apache.magma.basics.context.ContextElement;
+import org.apache.magma.basics.context.MultipleSegmentContextElement;
+import org.apache.magma.basics.context.RunningContext;
+import org.apache.magma.basics.context.SingleSegmentContextElement;
+import org.apache.magma.basics.context.SubRunningContext;
+
+/**
+ * Settings holder that fetch settings based on the current context.
+ * 
+ * <p>
+ * Each context is reduced to a collection of strings, using
+ * {...@link SingleSegmentContextElement#getSegment()} or
+ * {...@link MultipleSegmentContextElement#getSegments()}.
+ * </p>
+ * 
+ * <p>
+ * So for example, in a typical web application, we have a context
+ * like "html RootWebHandler handleSomething doSomething Form BeanName".
+ * </p>
+ * 
+ * <p>
+ * Each settings is expected to be composed of a number of segments,
+ * separated by a dot. Like for example :
+ * <pre>
+ * Form.style=something
+ * Form.BeanName.style=something else
+ * </pre>
+ * </p>
+ * 
+ * <p>
+ * The last segment is the real property name. So, when the property "style"
+ * is evaluated in a context containing "Form", it will evaluate so 
"something", while
+ * if the context contains "Form" followed (immediately or not) by "BeanName" 
then
+ * it will evaluate to "something else".
+ * </p>
+ * 
+ * @author Simone Gianni <[email protected]>
+ */
+public class ContextSettingsHolder extends SettingsHolder {
+
+       protected static final String CACHE_NONE = "___NONE___";
+               
+       protected Map<String, String> cache = new HashMap<String, String>();
+       protected Map<String, List<String[]>> firstLookup = new HashMap<String, 
List<String[]>>();
+       
+       @Override
+       public synchronized void inited() {
+               buildMatrix();
+               super.inited();
+       }
+       
+       /**
+        * Builds an inverted lookup table to speed up key resolution.
+        */
+       protected void buildMatrix() {
+               for (Map.Entry<Object, Object> entry : properties.entrySet()) {
+                       String[] parts = tokenize((String)entry.getKey(), 
(String)entry.getValue());
+                       String discriminator = parts[parts.length - 2];
+                       List<String[]> list = firstLookup.get(discriminator);
+                       if (list == null) {
+                               list = new ArrayList<String[]>();
+                               firstLookup.put(discriminator, list);
+                       }
+                       list.add(parts);
+               }
+       }
+       
+       protected static String[] tokenize(String key, String value) {
+               String[] parts = key.split("\\.");
+               parts = Arrays.copyOf(parts, parts.length + 1);
+               parts[parts.length - 1] = value;
+               return parts;
+       }
+       
+       @Override
+       public String get(String name) {
+               return get(RunningContext.get(), name);
+       }
+       
+       /**
+        * Gets the translation for the given string and the given context. 
+        * 
+        * The context is usually a {...@link SubRunningContext} instance.
+        * 
+        * @param ct A stack of elements representing the context.
+        * @param original The original string to translate.
+        * @return The translation or the original string if no translation 
found.
+        */
+       public String get(Stack<ContextElement> ct, String property) {
+               List<String[]> list = firstLookup.get(property);
+               // Fast not found case
+               if (list == null || list.size() == 0) return null;
+               
+               // Fast found xxxx=yyyyy case
+               if (list.size() == 1) {
+                       if (list.get(0).length == 2) {
+                               return list.get(0)[1];
+                       }
+               }
+               
+               String[] strings = stringify(ct);
+               StringBuilder keysb = new StringBuilder();
+               for (String string : strings) {
+                       keysb.append(string);
+                       keysb.append('.');
+               }
+               String key = keysb.toString();
+               String winner = cache.get(key);
+               if (winner == CACHE_NONE) return null;
+               if (winner == null) {
+                       int topscore = -1;
+                       for (String[] cm : list) {
+                               int score = getScore(cm, strings);
+                               if (score > topscore) {
+                                       topscore = score;
+                                       winner = cm[cm.length - 1];
+                               }
+                       }
+                       //ct.pop();
+                       if (winner == null) {
+                               cache.put(key, CACHE_NONE);
+                               return null;
+                       } else {
+                               cache.put(key, winner);
+                       }
+               }
+               return winner;
+       }
+       
+       /**
+        * Checks the score of two string arrays.
+        * @param parts The keys in the property file
+        * @param mc The keys of the context
+        * @return -1 for no match, 0 for one step match (x=y), increasingly 
higher score for more in depth match
+        */
+       protected static int getScore(String[] parts, String[] mc) {
+               if (parts.length == 2) return 0;
+               int total = -1;
+               int upto = 0;
+               int pos = 1;
+               for (String seg : mc) {
+                       pos++;
+                       if (parts[upto].equalsIgnoreCase(seg)) {
+                               upto++;
+                               total += pos;
+                               if (upto == parts.length - 2) return total;
+                       }
+               }
+               return -1;              
+       }
+
+       /**
+        * Converts a stack of context elements to an array of strings.
+        * @param ct The stack of the current context
+        * @return A string array, interpreting {...@link 
I18nMultiSegmentContextElement} with correct elements
+        */
+       protected static String[] stringify(Stack<ContextElement> ct) {
+               String[] ret = new String[ct.size() * 2];
+               int i = 0;
+               for (ContextElement ele : ct) {
+                       if (ele instanceof SingleSegmentContextElement) {
+                               String seg = 
((SingleSegmentContextElement)ele).getSegment();
+                               ret[i++] = seg;
+                       } else if (ele instanceof 
MultipleSegmentContextElement) {
+                               String[] segs = 
((MultipleSegmentContextElement)ele).getSegments();
+                               for (String seg : segs) {
+                                       ret[i++] = seg;
+                               }
+                       }
+               }
+               ret = Arrays.copyOf(ret, i);
+               return ret;
+       }
+       
+}

Modified: 
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/settings/SettingsHolder.java
URL: 
http://svn.apache.org/viewvc/labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/settings/SettingsHolder.java?rev=882400&r1=882399&r2=882400&view=diff
==============================================================================
--- 
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/settings/SettingsHolder.java
 (original)
+++ 
labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/settings/SettingsHolder.java
 Fri Nov 20 03:33:15 2009
@@ -40,9 +40,9 @@
  */
 public class SettingsHolder {
 
-       private Properties properties = new Properties();
-       private volatile boolean initing = false;
-       private volatile boolean inited = false;
+       protected Properties properties = new Properties();
+       protected volatile boolean initing = false;
+       protected volatile boolean inited = false;
        
        public synchronized boolean isInited() {
                return inited;
@@ -54,6 +54,8 @@
                                wait(1000);
                        } catch (InterruptedException e) {
                        }
+               } else {
+                       initing = true;
                }
        }
        

Added: 
labs/magma/trunk/foundation-basics/src/test/java/org/apache/magma/settings/ContextSettingsHolderTest.java
URL: 
http://svn.apache.org/viewvc/labs/magma/trunk/foundation-basics/src/test/java/org/apache/magma/settings/ContextSettingsHolderTest.java?rev=882400&view=auto
==============================================================================
--- 
labs/magma/trunk/foundation-basics/src/test/java/org/apache/magma/settings/ContextSettingsHolderTest.java
 (added)
+++ 
labs/magma/trunk/foundation-basics/src/test/java/org/apache/magma/settings/ContextSettingsHolderTest.java
 Fri Nov 20 03:33:15 2009
@@ -0,0 +1,109 @@
+package org.apache.magma.settings;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.apache.magma.settings.ContextSettingsHolder.stringify;
+import static org.apache.magma.settings.ContextSettingsHolder.tokenize;
+import static org.apache.magma.settings.ContextSettingsHolder.getScore;
+
+import java.lang.reflect.Method;
+import java.util.Stack;
+
+import org.apache.magma.basics.context.ContextElement;
+import org.apache.magma.basics.context.MethodContextElement;
+import org.apache.magma.basics.context.RunningContext;
+import org.apache.magma.basics.context.StringContextElement;
+import org.apache.magma.basics.context.SubRunningContext;
+import org.junit.After;
+import org.junit.Test;
+
+
+public class ContextSettingsHolderTest {
+
+       @Test
+       public void stringifyTest() throws Exception {
+               Stack<ContextElement> elements = new Stack<ContextElement>();
+               elements.push(new StringContextElement("text"));
+               Method m = 
ContextSettingsHolderTest.class.getMethod("stringifyTest");
+               elements.push(new MethodContextElement(m, new Object[0]));
+               
+               String[] strings = stringify(elements);
+               assertThat(strings[0], equalTo("text"));
+               assertThat(strings[1], 
equalTo(ContextSettingsHolderTest.class.getSimpleName()));
+               assertThat(strings[2], equalTo("stringifyTest"));
+       }       
+       
+       @SuppressWarnings("deprecation")
+       @After
+       public void cleanupRunningContext() {
+               RunningContext.cleanup();
+       }
+       
+       
+       @Test
+       public void simpleCompleteMatching() throws Exception {
+               SubRunningContext mc = RunningContext.get();
+               mc.push(getClass());
+               
+               int score = getScore(tokenize(getClass().getSimpleName() + 
".test", "test"), stringify(mc));
+               assertThat(score, equalTo(1));
+       }
+
+       @Test
+       public void simplePartialMatching() throws Exception {
+               SubRunningContext mc = RunningContext.get();
+               mc.push(getClass());
+               
+               int score = getScore(tokenize("test", "test"),stringify(mc));
+               assertTrue("Expected a match", score > -1);             
+       }
+       
+       @Test
+       public void simpleNotMatching() throws Exception {
+               SubRunningContext mc = RunningContext.get();
+               int score = getScore(tokenize(getClass().getSimpleName() + 
".test", "test"),stringify(mc));
+               assertThat(score, equalTo(-1));         
+       }
+       
+       @Test
+       public void simpleJumpingMatch() throws Exception {
+               SubRunningContext mc = RunningContext.get();
+               mc.push("testingthejump");
+               mc.push(getClass());
+               
+               int score = getScore(tokenize("testingthejump.test", 
"test"),stringify(mc));
+               assertTrue("Expected a match", score > -1);             
+       }
+       
+       @Test
+       public void betterMatch() throws Exception {
+               SubRunningContext mc = RunningContext.get();
+               mc.push("testingthejump");
+               mc.push(getClass());
+               
+               int score1 = getScore(tokenize("testingthejump.test", 
"test"),stringify(mc));
+               int score2 = getScore(tokenize("test", "test"),stringify(mc));
+               assertTrue(score1 + " is not > than " + score2, score1 > 
score2);               
+       }
+       
+       @Test
+       public void betterMatchAsPerBug184() throws Exception {
+               SubRunningContext mc = RunningContext.get();
+               mc.push("BahHtmlProducer");
+               mc.push("BeanFormProducer");
+               mc.push("UserBean");
+               mc.push("BeanFormProducer");
+               mc.push("UserBean");
+               mc.push("field1");
+               mc.push("field1");
+               mc.push("field2");
+               mc.push("field2");
+               mc.push("field2");
+               
+               int score1 = getScore(tokenize("UserBean.field2.key", "key"), 
stringify(mc));
+               int score2 = getScore(tokenize("UserBean.field1.key", "key"), 
stringify(mc));
+               assertTrue(score1 + " is not > than " + score2, score1 > 
score2);               
+       }
+       
+}

Added: 
labs/magma/trunk/foundation-basics/src/test/java/org/apache/magma/settings/PerformanceTest.java
URL: 
http://svn.apache.org/viewvc/labs/magma/trunk/foundation-basics/src/test/java/org/apache/magma/settings/PerformanceTest.java?rev=882400&view=auto
==============================================================================
--- 
labs/magma/trunk/foundation-basics/src/test/java/org/apache/magma/settings/PerformanceTest.java
 (added)
+++ 
labs/magma/trunk/foundation-basics/src/test/java/org/apache/magma/settings/PerformanceTest.java
 Fri Nov 20 03:33:15 2009
@@ -0,0 +1,170 @@
+package org.apache.magma.settings;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Stack;
+
+import org.apache.magma.basics.context.ClassContextElement;
+import org.apache.magma.basics.context.ContextElement;
+import org.apache.magma.basics.context.MethodContextElement;
+import org.apache.magma.basics.context.StringContextElement;
+import org.apache.magma.settings.SettingsHolder;
+import org.junit.Test;
+
+import static junit.framework.Assert.*;
+
+
+public class PerformanceTest {
+
+       
+       @Test
+       public void globalTest() throws Exception {
+               // Fill with a big number of possible permutations
+               ContextSettingsHolder lh = new ContextSettingsHolder();
+               
+               String[] elements = new String[] { "ajax", "String", "charAt", 
"ContextSettingsHolder", "inited", "Stack" };
+               for (int i = 4; i <= 255; i++) {
+                       String ele = "";
+                       for (int k = 0; k < elements.length; k++) {
+                               boolean add = (i & (1 << (k + 2))) != 0;
+                               if (add) 
+                                       ele += elements[k] + ".";
+                       }
+                       if ((i & 1) != 0) {
+                               ele += "notfound.";
+                       }
+                       if ((i & 2) != 0) {
+                               ele += "correct";
+                       } else {
+                               ele += "incorrect";
+                       }
+                       lh.override(ele, "ele " + i);
+               }
+               lh.inited();
+       
+               List<Stack<ContextElement>> contexts = generateContexts();
+               
+               // Time checking contexts agains the matrix
+               NanoTimer nt = new NanoTimer();
+               String ret = null;
+               int positives = 0;
+               int negatives = 0;
+               for (int i = 0; i < 1000000; i++) {
+                       Stack<ContextElement> stack = contexts.get(i % 
contexts.size());
+                       nt.start();
+                       ret = lh.get(stack, "correct");
+                       nt.stop(1);
+                       if (ret == null) {
+                               negatives++;
+                       } else {
+                               positives++;
+                       }
+                       if (i == 10000) {
+                               // ramp up
+                               //System.out.println(nt.status());
+                               //System.out.println("Ramped up");
+                               nt = new NanoTimer();
+                       } else if (i > 10000 && i % 1000 == 0) {
+                               //System.out.println(nt.status());
+                               nt.reset();
+                       }
+                       if (i > 10000 && i % 2000 == 0) {
+                               //System.out.println("Regenerating");
+                               contexts = generateContexts();
+                       }
+               }
+               System.out.println(nt.totals());
+               System.out.println("Positives : " + positives + "   Negatives : 
" + negatives);
+               System.out.println("Cache size : " + lh.cache.size());
+               assertEquals(600001, positives);
+               assertEquals(399999, negatives);
+               assertTrue("Poor performances", nt.totalIterationsPerSecond() > 
150000d);
+       }
+       
+       
+       static class NanoTimer {
+               private static double nanosInSecond = Math.pow(10, 9);
+               private long accumulated;
+               private long iterations;
+               
+               private long totalacc;
+               private long totaliter;
+               
+               private long start;
+               
+               public void start() {
+                       start = System.nanoTime();
+               }
+               public void stop(int iterations) {
+                       long elaps = System.nanoTime() - start;
+                       accumulated += elaps; 
+                       this.iterations += iterations;
+                       totaliter += iterations;
+                       totalacc += elaps;
+               }
+               public void reset() {
+                       accumulated = 0;
+                       iterations = 0;
+               }
+               public double nanosPerIteration() {
+                       return (double)accumulated / (double)iterations;
+               }
+               public double iterationsPerSecond() {
+                       return nanosInSecond / nanosPerIteration();
+               }
+               public String status() {
+                       return "Avg : " + nanosPerIteration() + " n/i = " + 
iterationsPerSecond() + " ips";
+               }
+               public double totalIterationsPerSecond() {
+                       double npi = (double)totalacc / (double)totaliter;
+                       return nanosInSecond / npi;
+               }
+               
+               public String totals() {
+                       double npi = (double)totalacc / (double)totaliter;
+                       double ips = nanosInSecond / npi;
+                       return "Total : " + npi + " n/i = " + ips + " ips   " + 
npi + "," + ips;
+               }
+       }
+       
+       private List<Stack<ContextElement>> generateContexts() throws Exception 
{
+               List<ContextElement> ce = new ArrayList<ContextElement>();
+               ce.add(new StringContextElement("ajax"));
+               Method m = String.class.getMethod("charAt", Integer.TYPE);
+               ce.add(new MethodContextElement(m, new Object[] { 1 }));
+               m = ContextSettingsHolder.class.getMethod("inited");
+               ce.add(new MethodContextElement(m, new Object[] {}));
+               ce.add(new ClassContextElement(Stack.class));
+               
+               List<Stack<ContextElement>> contexts = new 
ArrayList<Stack<ContextElement>>(15);
+               for (int i = 1; i <= 15; i++) {
+                       Stack<ContextElement> ctx = new Stack<ContextElement>();
+                       for (int k = 0; k < ce.size(); k++) {
+                               boolean add = (i & (1 << k)) != 0;
+                               if (add) 
+                                       ctx.push(ce.get(k));
+                       }
+                       contexts.add(ctx);
+               }
+               
+               ce = new ArrayList<ContextElement>();
+               ce.add(new StringContextElement("web"));
+               m = Integer.class.getMethod("compareTo", Integer.class);
+               ce.add(new MethodContextElement(m, new Object[] { 1 }));
+               m = SettingsHolder.class.getMethod("initing");
+               ce.add(new MethodContextElement(m, new Object[] {}));
+               ce.add(new ClassContextElement(Stack.class));           
+               for (int i = 1; i <= 50; i++) {
+                       Stack<ContextElement> ctx = new Stack<ContextElement>();
+                       for (int k = 0; k < ce.size(); k++) {
+                               boolean add = (i & (1 << k)) != 0;
+                               if (add) 
+                                       ctx.push(ce.get(k));
+                       }
+                       contexts.add(ctx);                      
+               }
+               return contexts;
+       }
+}

Modified: 
labs/magma/trunk/foundation-i18n/src/main/java/org/apache/magma/i18n/LocaleHolder.java
URL: 
http://svn.apache.org/viewvc/labs/magma/trunk/foundation-i18n/src/main/java/org/apache/magma/i18n/LocaleHolder.java?rev=882400&r1=882399&r2=882400&view=diff
==============================================================================
--- 
labs/magma/trunk/foundation-i18n/src/main/java/org/apache/magma/i18n/LocaleHolder.java
 (original)
+++ 
labs/magma/trunk/foundation-i18n/src/main/java/org/apache/magma/i18n/LocaleHolder.java
 Fri Nov 20 03:33:15 2009
@@ -31,6 +31,7 @@
 
 import org.apache.magma.basics.context.ContextElement;
 import org.apache.magma.basics.context.SubRunningContext;
+import org.apache.magma.settings.ContextSettingsHolder;
 import org.apache.magma.settings.SettingsHolder;
 
 /**
@@ -43,14 +44,8 @@
  */
 public class LocaleHolder {
 
-       protected static final String CACHE_NONE = "___NONE___";
-       
        protected Locale locale;
-       protected SettingsHolder messages = new SettingsHolder();
-       protected Map<String, String> cache = new HashMap<String, String>();
-       
-       
-       protected Map<String, List<String[]>> firstLookup = new HashMap<String, 
List<String[]>>();
+       protected ContextSettingsHolder messages = new ContextSettingsHolder();
        
        /**
         * Creates an instance
@@ -59,7 +54,6 @@
        public LocaleHolder(Locale locale) {
                this.locale = locale;               
            initMessages();
-           buildMatrix();
        }
 
        /**
@@ -114,25 +108,6 @@
        }
        
        /**
-        * Builds an inverted lookup table to speed up key resolution.
-        */
-       public void buildMatrix() {
-               Map<String, String> all = messages.getAll();
-               for (Map.Entry<String, String> entry : all.entrySet()) {
-                       String[] parts = entry.getKey().split("\\.");
-                       parts = Arrays.copyOf(parts, parts.length + 1);
-                       parts[parts.length - 1] = entry.getValue();
-                       String discriminator = parts[parts.length - 2];
-                       List<String[]> list = firstLookup.get(discriminator);
-                       if (list == null) {
-                               list = new ArrayList<String[]>();
-                               firstLookup.put(discriminator, list);
-                       }
-                       list.add(parts);
-               }
-       }
-       
-       /**
         * Gets the translation for the given string and the given context. 
         * 
         * The context is usually a {...@link SubRunningContext} instance.
@@ -143,93 +118,12 @@
         */
        public String getMessage(Stack<ContextElement> ct, String original) {
                String deh = normalize(original);
-               List<String[]> list = firstLookup.get(deh);
-               // Fast not found case
-               if (list == null || list.size() == 0) return original;
-               
-               // Fast found xxxx=yyyyy case
-               if (list.size() == 1) {
-                       if (list.get(0).length == 2) {
-                               return list.get(0)[1];
-                       }
-               }
-               
-               String[] strings = stringify(ct);
-               StringBuilder keysb = new StringBuilder();
-               for (String string : strings) {
-                       keysb.append(string);
-                       keysb.append('.');
-               }
-               String key = keysb.toString();
-               String winner = cache.get(key);
-               if (winner == CACHE_NONE) return original;
-               if (winner == null) {
-                       int topscore = -1;
-                       for (String[] cm : list) {
-                               int score = getScore(cm, strings);
-                               if (score > topscore) {
-                                       topscore = score;
-                                       winner = cm[cm.length - 1];
-                               }
-                       }
-                       //ct.pop();
-                       if (winner == null) {
-                               cache.put(key, CACHE_NONE);
-                               return original;
-                       } else {
-                               cache.put(key, winner);
-                       }
-               }
-               return winner;
-       }
-       
-       /**
-        * Checks the score of two string arrays.
-        * @param parts The keys in the property file
-        * @param mc The keys of the context
-        * @return -1 for no match, 0 for one step match (x=y), increasingly 
higher score for more in depth match
-        */
-       protected static int getScore(String[] parts, String[] mc) {
-               if (parts.length == 1) return 0;
-               int total = -1;
-               int upto = 0;
-               int pos = 1;
-               for (String seg : mc) {
-                       pos++;
-                       if (parts[upto].equalsIgnoreCase(seg)) {
-                               upto++;
-                               total += pos;
-                               if (upto == parts.length - 2) return total;
-                       }
-               }
-               return -1;              
-       }
-
-       /**
-        * Converts a stack of context elements to an array of strings.
-        * @param ct The stack of the current context
-        * @return A string array, interpreting {...@link 
I18nMultiSegmentContextElement} with correct elements
-        */
-       protected static String[] stringify(Stack<ContextElement> ct) {
-               String[] ret = new String[ct.size() * 2];
-               int i = 0;
-               for (ContextElement ele : ct) {
-                       if (ele instanceof I18nContextElement) {
-                               if (ele instanceof 
I18nSingleSegmentContextElement) {
-                                       String seg = 
((I18nSingleSegmentContextElement)ele).getI18nSegment();
-                                       ret[i++] = seg;
-                               } else {
-                                       String[] segs = 
((I18nMultiSegmentContextElement)ele).getI18nSegments();
-                                       for (String seg : segs) {
-                                               ret[i++] = seg;
-                                       }
-                               }
-                       }
-               }
-               ret = Arrays.copyOf(ret, i);
+               String ret = messages.get(ct, deh);
+               if (ret == null) return original;
                return ret;
        }
        
+       
        /**
         * Transforms a string into a key.
         * 



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to