Repository: incubator-freemarker Updated Branches: refs/heads/2.3-gae 55b09e8de -> 6e15268f7
(Minor code cleanup in ext.dom; no functional changes) Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/6e15268f Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/6e15268f Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/6e15268f Branch: refs/heads/2.3-gae Commit: 6e15268f7812ebc659ab197c47681ed8b7b076f1 Parents: 55b09e8 Author: ddekany <[email protected]> Authored: Thu Jan 12 08:46:06 2017 +0100 Committer: ddekany <[email protected]> Committed: Thu Jan 12 08:46:06 2017 +0100 ---------------------------------------------------------------------- .../java/freemarker/core/CustomAttribute.java | 1 + .../java/freemarker/ext/dom/DocumentModel.java | 2 +- .../java/freemarker/ext/dom/DomStringUtil.java | 8 ++--- .../java/freemarker/ext/dom/ElementModel.java | 8 ++--- .../freemarker/ext/dom/JaxenXPathSupport.java | 37 ++++++++++++-------- .../java/freemarker/ext/dom/NodeListModel.java | 10 +++--- .../java/freemarker/ext/dom/XPathSupport.java | 3 ++ .../java/freemarker/ext/dom/_ExtDomApi.java | 4 +-- .../java/freemarker/template/_TemplateAPI.java | 2 +- .../freemarker/template/utility/StringUtil.java | 2 +- 10 files changed, 44 insertions(+), 33 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6e15268f/src/main/java/freemarker/core/CustomAttribute.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/core/CustomAttribute.java b/src/main/java/freemarker/core/CustomAttribute.java index fe55eb9..249a97f 100644 --- a/src/main/java/freemarker/core/CustomAttribute.java +++ b/src/main/java/freemarker/core/CustomAttribute.java @@ -40,6 +40,7 @@ import freemarker.template.Template; * myAttrValue = MY_ATTR.get(cfg); * </pre> */ +// [2.4] Use generics; type parameter used for the type of the stored value public class CustomAttribute { /** http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6e15268f/src/main/java/freemarker/ext/dom/DocumentModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/dom/DocumentModel.java b/src/main/java/freemarker/ext/dom/DocumentModel.java index fb161e0..06fe9dc 100644 --- a/src/main/java/freemarker/ext/dom/DocumentModel.java +++ b/src/main/java/freemarker/ext/dom/DocumentModel.java @@ -52,7 +52,7 @@ class DocumentModel extends NodeModel implements TemplateHashModel { } else if (key.equals("**")) { NodeList nl = ((Document) node).getElementsByTagName("*"); return new NodeListModel(nl, this); - } else if (DomStringUtil.isXMLID(key)) { + } else if (DomStringUtil.isXMLNameLike(key)) { ElementModel em = (ElementModel) NodeModel.wrap(((Document) node).getDocumentElement()); if (em.matchesName(key, Environment.getCurrentEnvironment())) { return em; http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6e15268f/src/main/java/freemarker/ext/dom/DomStringUtil.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/dom/DomStringUtil.java b/src/main/java/freemarker/ext/dom/DomStringUtil.java index 85df716..b93192b 100644 --- a/src/main/java/freemarker/ext/dom/DomStringUtil.java +++ b/src/main/java/freemarker/ext/dom/DomStringUtil.java @@ -33,19 +33,19 @@ final class DomStringUtil { // Not meant to be instantiated } - static boolean isXMLID(String name) { - return isXMLID(name, 0); + static boolean isXMLNameLike(String name) { + return isXMLNameLike(name, 0); } /** - * Check if the subvariable name is just an element name, or a more complex XPath expression. + * Check if the name looks like an XML element name. * * @param firstCharIdx The index of the character in the string parameter that we treat as the beginning of the * string to check. This is to spare substringing that has become more expensive in Java 7. * * @return whether the name is a valid XML element name. (This routine might only be 99% accurate. REVISIT) */ - static boolean isXMLID(String name, int firstCharIdx) { + static boolean isXMLNameLike(String name, int firstCharIdx) { int ln = name.length(); for (int i = firstCharIdx; i < ln; i++) { char c = name.charAt(i); http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6e15268f/src/main/java/freemarker/ext/dom/ElementModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/dom/ElementModel.java b/src/main/java/freemarker/ext/dom/ElementModel.java index 21d0a35..3fbc15c 100644 --- a/src/main/java/freemarker/ext/dom/ElementModel.java +++ b/src/main/java/freemarker/ext/dom/ElementModel.java @@ -106,11 +106,11 @@ class ElementModel extends NodeModel implements TemplateScalarModel { return wrap(nextSibling); } } else { - // We don't anything like this that's element-specific; fall back + // We don't know anything like this that's element-specific; fall back return super.get(key); } } else { // Starts with "@", but not with "@@" - if (DomStringUtil.isXMLID(key, 1)) { + if (DomStringUtil.isXMLNameLike(key, 1)) { Attr att = getAttribute(key.substring(1)); if (att == null) { return new NodeListModel(this); @@ -119,11 +119,11 @@ class ElementModel extends NodeModel implements TemplateScalarModel { } else if (key.equals("@*")) { return new NodeListModel(node.getAttributes(), this); } else { - // We don't anything like this that's element-specific; fall back + // We don't know anything like this that's element-specific; fall back return super.get(key); } } - } else if (DomStringUtil.isXMLID(key)) { + } else if (DomStringUtil.isXMLNameLike(key)) { // We interpret key as an element name NodeListModel result = ((NodeListModel) getChildNodes()).filterByName(key); return result.size() != 1 ? result : result.get(0); http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6e15268f/src/main/java/freemarker/ext/dom/JaxenXPathSupport.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/dom/JaxenXPathSupport.java b/src/main/java/freemarker/ext/dom/JaxenXPathSupport.java index ae10569..109e82b 100644 --- a/src/main/java/freemarker/ext/dom/JaxenXPathSupport.java +++ b/src/main/java/freemarker/ext/dom/JaxenXPathSupport.java @@ -65,32 +65,34 @@ import freemarker.template.utility.UndeclaredThrowableException; */ class JaxenXPathSupport implements XPathSupport { - private static final CustomAttribute cache = + private static final CustomAttribute XPATH_CACHE_ATTR = new CustomAttribute(CustomAttribute.SCOPE_TEMPLATE) { @Override protected Object create() { - return new HashMap(); + return new HashMap<String, BaseXPath>(); } }; + // [2.4] Can't we just use Collections.emptyList()? private final static ArrayList EMPTY_ARRAYLIST = new ArrayList(); public TemplateModel executeQuery(Object context, String xpathQuery) throws TemplateModelException { try { BaseXPath xpath; - Map xpathCache = (Map) cache.get(); + Map<String, BaseXPath> xpathCache = (Map<String, BaseXPath>) XPATH_CACHE_ATTR.get(); synchronized (xpathCache) { - xpath = (BaseXPath) xpathCache.get(xpathQuery); + xpath = xpathCache.get(xpathQuery); if (xpath == null) { - xpath = new BaseXPath(xpathQuery, fmDomNavigator); + xpath = new BaseXPath(xpathQuery, FM_DOM_NAVIGATOR); xpath.setNamespaceContext(customNamespaceContext); - xpath.setFunctionContext(fmFunctionContext); - xpath.setVariableContext(fmVariableContext); + xpath.setFunctionContext(FM_FUNCTION_CONTEXT); + xpath.setVariableContext(FM_VARIABLE_CONTEXT); xpathCache.put(xpathQuery, xpath); } } List result = xpath.selectNodes(context != null ? context : EMPTY_ARRAYLIST); if (result.size() == 1) { + // [2.4] Use the proper object wrapper (argument in 2.4) return ObjectWrapper.DEFAULT_WRAPPER.wrap(result.get(0)); } NodeListModel nlm = new NodeListModel(result, null); @@ -117,13 +119,13 @@ class JaxenXPathSupport implements XPathSupport { } }; - private static final VariableContext fmVariableContext = new VariableContext() { + private static final VariableContext FM_VARIABLE_CONTEXT = new VariableContext() { public Object getVariableValue(String namespaceURI, String prefix, String localName) throws UnresolvableException { try { TemplateModel model = Environment.getCurrentEnvironment().getVariable(localName); if (model == null) { - throw new UnresolvableException("Variable " + localName + " not found."); + throw new UnresolvableException("Variable \"" + localName + "\" not found."); } if (model instanceof TemplateScalarModel) { return ((TemplateScalarModel) model).getAsString(); @@ -140,11 +142,12 @@ class JaxenXPathSupport implements XPathSupport { } catch (TemplateModelException e) { throw new UndeclaredThrowableException(e); } - throw new UnresolvableException("Variable " + localName + " is not a string, number, date, or boolean"); + throw new UnresolvableException( + "Variable \"" + localName + "\" exists, but it's not a string, number, date, or boolean"); } }; - private static final FunctionContext fmFunctionContext = new XPathFunctionContext() { + private static final FunctionContext FM_FUNCTION_CONTEXT = new XPathFunctionContext() { @Override public Function getFunction(String namespaceURI, String prefix, String localName) throws UnresolvableException { @@ -156,14 +159,18 @@ class JaxenXPathSupport implements XPathSupport { } }; - private static final CustomAttribute cachedTree = new CustomAttribute(CustomAttribute.SCOPE_TEMPLATE); + /** + * Stores the the template parsed as {@link Document} in the template itself. + */ + private static final CustomAttribute FM_DOM_NAVIAGOTOR_CACHED_DOM + = new CustomAttribute(CustomAttribute.SCOPE_TEMPLATE); - private static final Navigator fmDomNavigator = new DocumentNavigator() { + private static final Navigator FM_DOM_NAVIGATOR = new DocumentNavigator() { @Override public Object getDocument(String uri) throws FunctionCallException { try { Template raw = getTemplate(uri); - Document doc = (Document) cachedTree.get(raw); + Document doc = (Document) FM_DOM_NAVIAGOTOR_CACHED_DOM.get(raw); if (doc == null) { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); @@ -174,7 +181,7 @@ class JaxenXPathSupport implements XPathSupport { // If the entity resolver got called 0 times, the document // is standalone, so we can safely cache it if (er.getCallCount() == 0) { - cachedTree.set(doc, raw); + FM_DOM_NAVIAGOTOR_CACHED_DOM.set(doc, raw); } } return doc; http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6e15268f/src/main/java/freemarker/ext/dom/NodeListModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/dom/NodeListModel.java b/src/main/java/freemarker/ext/dom/NodeListModel.java index 4a37266..b375478 100644 --- a/src/main/java/freemarker/ext/dom/NodeListModel.java +++ b/src/main/java/freemarker/ext/dom/NodeListModel.java @@ -40,7 +40,6 @@ import freemarker.template.TemplateNodeModel; import freemarker.template.TemplateNumberModel; import freemarker.template.TemplateScalarModel; import freemarker.template.TemplateSequenceModel; -import freemarker.template.utility.StringUtil; /** * Used when the result set contains 0 or multiple nodes; shouldn't be used when you have exactly 1 node. For exactly 1 @@ -49,6 +48,7 @@ import freemarker.template.utility.StringUtil; */ class NodeListModel extends SimpleSequence implements TemplateHashModel, _UnexpectedTypeErrorExplainerTemplateModel { + // [2.4] make these private NodeModel contextNode; XPathSupport xpathSupport; @@ -61,8 +61,8 @@ class NodeListModel extends SimpleSequence implements TemplateHashModel, _Unexpe } }; - NodeListModel(Node node) { - this(NodeModel.wrap(node)); + NodeListModel(Node contextNode) { + this(NodeModel.wrap(contextNode)); } NodeListModel(NodeModel contextNode) { @@ -142,9 +142,9 @@ class NodeListModel extends SimpleSequence implements TemplateHashModel, _Unexpe } } } - if (DomStringUtil.isXMLID(key) + if (DomStringUtil.isXMLNameLike(key) || ((key.startsWith("@") - && (DomStringUtil.isXMLID(key, 1) || key.equals("@@") || key.equals("@*")))) + && (DomStringUtil.isXMLNameLike(key, 1) || key.equals("@@") || key.equals("@*")))) || key.equals("*") || key.equals("**")) { NodeListModel result = new NodeListModel(contextNode); for (int i = 0; i < size(); i++) { http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6e15268f/src/main/java/freemarker/ext/dom/XPathSupport.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/dom/XPathSupport.java b/src/main/java/freemarker/ext/dom/XPathSupport.java index 2d928c3..e51d812 100644 --- a/src/main/java/freemarker/ext/dom/XPathSupport.java +++ b/src/main/java/freemarker/ext/dom/XPathSupport.java @@ -23,5 +23,8 @@ import freemarker.template.TemplateModel; import freemarker.template.TemplateModelException; public interface XPathSupport { + + // [2.4] Add argument to pass down the ObjectWrapper to use TemplateModel executeQuery(Object context, String xpathQuery) throws TemplateModelException; + } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6e15268f/src/main/java/freemarker/ext/dom/_ExtDomApi.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/dom/_ExtDomApi.java b/src/main/java/freemarker/ext/dom/_ExtDomApi.java index 70ec0e4..178d8a8 100644 --- a/src/main/java/freemarker/ext/dom/_ExtDomApi.java +++ b/src/main/java/freemarker/ext/dom/_ExtDomApi.java @@ -32,8 +32,8 @@ public final class _ExtDomApi { // Not meant to be called } - static public boolean isXMLID(String name) { - return DomStringUtil.isXMLID(name); + static public boolean isXMLNameLike(String name) { + return DomStringUtil.isXMLNameLike(name); } static public boolean matchesName(String qname, String nodeName, String nsURI, Environment env) { http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6e15268f/src/main/java/freemarker/template/_TemplateAPI.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/template/_TemplateAPI.java b/src/main/java/freemarker/template/_TemplateAPI.java index c55a113..52606f6 100644 --- a/src/main/java/freemarker/template/_TemplateAPI.java +++ b/src/main/java/freemarker/template/_TemplateAPI.java @@ -100,7 +100,7 @@ public class _TemplateAPI { } /** - * [FM 2.4] getSettingNames() becomes to public; remove this. + * [2.4] getSettingNames() becomes to public; remove this. */ public static Set/*<String>*/ getConfigurationSettingNames(Configuration cfg, boolean camelCase) { return cfg.getSettingNames(camelCase); http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6e15268f/src/main/java/freemarker/template/utility/StringUtil.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/template/utility/StringUtil.java b/src/main/java/freemarker/template/utility/StringUtil.java index 27db53f..55ba617 100644 --- a/src/main/java/freemarker/template/utility/StringUtil.java +++ b/src/main/java/freemarker/template/utility/StringUtil.java @@ -1663,7 +1663,7 @@ public class StringUtil { */ @Deprecated static public boolean isXMLID(String name) { - return _ExtDomApi.isXMLID(name); + return _ExtDomApi.isXMLNameLike(name); } /**
