You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@labs.apache.org by si...@apache.org on 2009/11/20 04:33:18 UTC
svn commit: r882400 - in /labs/magma/trunk:
foundation-basics/src/main/java/org/apache/magma/basics/context/
foundation-basics/src/main/java/org/apache/magma/settings/
foundation-basics/src/test/java/org/apache/magma/settings/
foundation-i18n/src/main/...
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 <si...@apache.org>
*/
-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 <si...@apache.org>
*/
-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 <si...@apache.org>
*/
-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 <si...@apache.org>
+ */
+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: commits-unsubscribe@labs.apache.org
For additional commands, e-mail: commits-help@labs.apache.org