Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpelder2007-11-29 16:37:06 -0500
committerpelder2007-11-29 16:37:06 -0500
commita4c9493d7975f62c685030e045647914f641f57b (patch)
treefcb04be39ac5da7c77647e4cfcef71f9ecd337e1
parent048275e14b3d346eba92638f7b5f778b4ad9aa3d (diff)
downloadorg.eclipse.jet-a4c9493d7975f62c685030e045647914f641f57b.tar.gz
org.eclipse.jet-a4c9493d7975f62c685030e045647914f641f57b.tar.xz
org.eclipse.jet-a4c9493d7975f62c685030e045647914f641f57b.zip
[211505] Performance: Compile Patterns only once in XPathContextExtender
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/XPathContextExtender.java116
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/taglib/AbstractCustomTag.java3
2 files changed, 72 insertions, 47 deletions
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/XPathContextExtender.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/XPathContextExtender.java
index b4f0ad4..0ddee32 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/XPathContextExtender.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/XPathContextExtender.java
@@ -55,19 +55,26 @@ import org.eclipse.jet.xpath.inspector.INodeInspector.NodeKind;
* Context Extender that understands XPath processing.
*
*/
-public final class XPathContextExtender extends AbstractContextExtender implements XPathVariableResolver
+public final class XPathContextExtender implements XPathVariableResolver
{
+ private static String PRIVATE_CONTEXT_DATA_KEY = XPathContextExtender.class.getName();
+
+ private static final Pattern DYNAMIC_XPATH = Pattern.compile("\\{(.*?)}"); //$NON-NLS-1$
private static boolean DEBUG = InternalJET2Platform.getDefault().isDebugging()
&& Boolean.valueOf(Platform.getDebugOption("org.eclipse.jet/debug/xpath/compilations")).booleanValue(); //$NON-NLS-1$
+ private final ContextData contextData;
+
+ private final JET2Context context;
+
private static final class ContextData
{
- private final IAnnotationManager annotationManager = new AnnotationManagerImpl();
+ public final IAnnotationManager annotationManager = new AnnotationManagerImpl();
- private DefaultXPathFunctionResolver customFunctionResolver = null;
+ public DefaultXPathFunctionResolver customFunctionResolver = null;
- private final Map knownXPathExpressions = new HashMap();
+ public final Map knownXPathExpressions = new HashMap();
}
/**
@@ -76,7 +83,17 @@ public final class XPathContextExtender extends AbstractContextExtender implemen
*/
public XPathContextExtender(JET2Context context)
{
- super(context);
+ this(context, getInstance(context).contextData);
+ }
+
+ private XPathContextExtender(JET2Context context, ContextData contextData)
+ {
+ this.context = context;
+ this.contextData = contextData;
+ XPath xp = XPathFactory.newInstance().newXPath(contextData.annotationManager);
+ // Add one a custom function resolver which delegates to the resolver installed by default.
+ contextData.customFunctionResolver = new DefaultXPathFunctionResolver(xp.getXPathFunctionResolver());
+
}
/**
@@ -86,7 +103,16 @@ public final class XPathContextExtender extends AbstractContextExtender implemen
*/
public static XPathContextExtender getInstance(JET2Context context)
{
- return new XPathContextExtender(context);
+ if(context == null) {
+ throw new NullPointerException();
+ }
+ XPathContextExtender ex = (XPathContextExtender)context.getPrivateData(PRIVATE_CONTEXT_DATA_KEY);
+ if (ex == null)
+ {
+ ex = new XPathContextExtender(context, new ContextData());
+ context.addPrivateData(PRIVATE_CONTEXT_DATA_KEY, ex);
+ }
+ return ex;
}
/* (non-Javadoc)
* @see org.eclipse.jet.AbstractContextExtender#createExtendedData(org.eclipse.jet.JET2Context)
@@ -102,28 +128,15 @@ public final class XPathContextExtender extends AbstractContextExtender implemen
return contextData;
}
- private ContextData getData()
- {
- return (ContextData)getExtendedData();
- }
-
public Object resolveVariable(String name)
{
- // return getData().xpathVariableMap.get(name);
- if (getContext().hasVariable(name))
+ try
{
- try
- {
- return getContext().getVariable(name);
- }
- catch (JET2TagException e)
- {
- // wont' happen, we checked to make sure its ok.;
- return null;
- }
+ return context.getVariable(name);
}
- else
+ catch (JET2TagException e)
{
+ // var not defined, just return null
return null;
}
}
@@ -176,13 +189,13 @@ public final class XPathContextExtender extends AbstractContextExtender implemen
*/
private XPathExpression compileXPath(String selectXPath) throws XPathException
{
- Object result = getData().knownXPathExpressions.get(selectXPath);
+ Object result = contextData.knownXPathExpressions.get(selectXPath);
if (result == null)
{
if(DEBUG) System.out.println("XPath compile of " + selectXPath); //$NON-NLS-1$
- XPath xp = XPathFactory.newInstance().newXPath(getData().annotationManager);
+ XPath xp = XPathFactory.newInstance().newXPath(contextData.annotationManager);
// install the custom resolver.
- xp.setXPathFunctionResolver(getData().customFunctionResolver);
+ xp.setXPathFunctionResolver(contextData.customFunctionResolver);
xp.setXPathVariableResolver(this);
try
{
@@ -194,7 +207,7 @@ public final class XPathContextExtender extends AbstractContextExtender implemen
result = e;
if(DEBUG) System.out.println(" exception " + result); //$NON-NLS-1$
}
- getData().knownXPathExpressions.put(selectXPath, result);
+ contextData.knownXPathExpressions.put(selectXPath, result);
} else {
if(DEBUG) System.out.println("XPath cache hit on " + selectXPath); //$NON-NLS-1$
}
@@ -210,7 +223,7 @@ public final class XPathContextExtender extends AbstractContextExtender implemen
public Object currentXPathContextObject()
{
- return getContext().getSource();
+ return context.getSource();
}
public Object[] resolve(Object xpathContextObject, String selectXPath) throws JET2TagException
@@ -264,8 +277,8 @@ public final class XPathContextExtender extends AbstractContextExtender implemen
// continue, ;
}
- if(!isSet && getData().annotationManager != null) {
- Object annotation = getData().annotationManager.getAnnotationObject(element);
+ if(!isSet && contextData.annotationManager != null) {
+ Object annotation = contextData.annotationManager.getAnnotationObject(element);
elementInspector = getElementInspector(annotation);
isSet = elementInspector.createAttribute(annotation, name, bodyContent);
}
@@ -280,25 +293,38 @@ public final class XPathContextExtender extends AbstractContextExtender implemen
*/
public String resolveDynamic(String value) throws JET2TagException
{
- Object context = currentXPathContextObject();
- Pattern dynXpathPattern = Pattern.compile("\\{(.*?)}"); // look for a sequence of characters between { and } //$NON-NLS-1$
- StringBuffer buffer = new StringBuffer(value);
- Matcher matcher = dynXpathPattern.matcher(buffer);
- int i = 0;
- while (i < buffer.length() && matcher.find(i))
- {
- String xpath = matcher.group(1);
- String resolved = resolveAsString(context, xpath);
+ Matcher matcher = DYNAMIC_XPATH.matcher(value);
+ return matcher.find() ? internalResolveDynamic(value, matcher) : value;
+ }
+
+ public static String resolveDynamic(String value, JET2Context context) throws JET2TagException
+ {
+ Matcher matcher = DYNAMIC_XPATH.matcher(value);
+ if(matcher.find()) {
+ return getInstance(context).internalResolveDynamic(value, matcher);
+ }
+ return value;
+ }
+
+ private String internalResolveDynamic(String value, Matcher matcher)
+ {
+ final Object contextObject = currentXPathContextObject();
+ final StringBuffer buffer = new StringBuffer(value);
+ int fudgeFactor = 0;
+ do {
+ final String xpath = matcher.group(1);
+ final String resolved = resolveAsString(contextObject, xpath);
if (resolved == null)
{
String msg = JET2Messages.XPath_DynamicExpressionIsNull;
throw new JET2TagException(MessageFormat.format(msg, new Object []{ xpath }));
}
- buffer.replace(matcher.start(), matcher.end(), resolved);
- // next scan starts at end of this match, adjusted for the size difference between
- // the replacement text (resolved.length()) and the replaced text xpath.length() + 2 (for { & }).
- i = matcher.end() + resolved.length() - (xpath.length() + 2);
- }
+ final int mStart = matcher.start();
+ final int mEnd = matcher.end();
+ buffer.replace(fudgeFactor + mStart, fudgeFactor + mEnd, resolved);
+ final int mLen = mEnd - mStart;
+ fudgeFactor += resolved.length() - mLen;
+ } while(matcher.find());
return buffer.toString();
}
@@ -510,7 +536,7 @@ public final class XPathContextExtender extends AbstractContextExtender implemen
*/
public void addCustomFunctions(XPathFunctionMetaData functionData[])
{
- final DefaultXPathFunctionResolver resolver = getData().customFunctionResolver;
+ final DefaultXPathFunctionResolver resolver = contextData.customFunctionResolver;
for (int i = 0; i < functionData.length; i++)
{
resolver.addFunction(functionData[i]);
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/taglib/AbstractCustomTag.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/taglib/AbstractCustomTag.java
index 69189f1..85e954b 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/taglib/AbstractCustomTag.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/taglib/AbstractCustomTag.java
@@ -93,8 +93,7 @@ public abstract class AbstractCustomTag implements CustomTag
String raw = getRawAttribute(name);
if (raw != null)
{
- XPathContextExtender xpathExtender = XPathContextExtender.getInstance(context);
- return xpathExtender.resolveDynamic(raw);
+ return XPathContextExtender.resolveDynamic(raw, context);
}
return null;
}

Back to the top