1. /*
  2. * Copyright 1999-2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.apache.commons.jxpath;
  17. import java.util.ArrayList;
  18. import java.util.HashMap;
  19. import java.util.Iterator;
  20. import java.util.List;
  21. import java.util.Set;
  22. /**
  23. * An object that aggregates Functions objects into a group Functions object.
  24. * Since JXPathContext can only register a single Functions object,
  25. * FunctionLibrary should always be used to group all Functions objects
  26. * that need to be registered.
  27. *
  28. * @author Dmitri Plotnikov
  29. * @version $Revision: 1.5 $ $Date: 2004/02/29 14:17:42 $
  30. */
  31. public class FunctionLibrary implements Functions {
  32. private List allFunctions = new ArrayList();
  33. private HashMap byNamespace = null;
  34. /**
  35. * Add functions to the library
  36. */
  37. public void addFunctions(Functions functions) {
  38. allFunctions.add(functions);
  39. byNamespace = null;
  40. }
  41. /**
  42. * Remove functions from the library.
  43. */
  44. public void removeFunctions(Functions functions) {
  45. allFunctions.remove(functions);
  46. byNamespace = null;
  47. }
  48. /**
  49. * Returns a set containing all namespaces used by the aggregated
  50. * Functions.
  51. */
  52. public Set getUsedNamespaces() {
  53. if (byNamespace == null) {
  54. prepareCache();
  55. }
  56. return byNamespace.keySet();
  57. }
  58. /**
  59. * Returns a Function, if any, for the specified namespace,
  60. * name and parameter types.
  61. */
  62. public Function getFunction(
  63. String namespace,
  64. String name,
  65. Object[] parameters)
  66. {
  67. if (byNamespace == null) {
  68. prepareCache();
  69. }
  70. Object candidates = byNamespace.get(namespace);
  71. if (candidates instanceof Functions) {
  72. return ((Functions) candidates).getFunction(
  73. namespace,
  74. name,
  75. parameters);
  76. }
  77. else if (candidates instanceof List) {
  78. List list = (List) candidates;
  79. int count = list.size();
  80. for (int i = 0; i < count; i++) {
  81. Function function =
  82. ((Functions) list.get(i)).getFunction(
  83. namespace,
  84. name,
  85. parameters);
  86. if (function != null) {
  87. return function;
  88. }
  89. }
  90. }
  91. return null;
  92. }
  93. private void prepareCache() {
  94. byNamespace = new HashMap();
  95. int count = allFunctions.size();
  96. for (int i = 0; i < count; i++) {
  97. Functions funcs = (Functions) allFunctions.get(i);
  98. Set namespaces = funcs.getUsedNamespaces();
  99. for (Iterator it = namespaces.iterator(); it.hasNext();) {
  100. String ns = (String) it.next();
  101. Object candidates = byNamespace.get(ns);
  102. if (candidates == null) {
  103. byNamespace.put(ns, funcs);
  104. }
  105. else if (candidates instanceof Functions) {
  106. List lst = new ArrayList();
  107. lst.add(candidates);
  108. lst.add(funcs);
  109. byNamespace.put(ns, lst);
  110. }
  111. else {
  112. ((List) candidates).add(funcs);
  113. }
  114. }
  115. }
  116. }
  117. }