You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

ScriptFixBSFPath.java 5.2 kB

11 years ago
5 years ago
5 years ago
8 years ago
7 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * https://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. package org.apache.tools.ant.util;
  19. import java.io.File;
  20. import java.util.HashMap;
  21. import java.util.Map;
  22. import org.apache.tools.ant.AntClassLoader;
  23. import org.apache.tools.ant.BuildException;
  24. import org.apache.tools.ant.MagicNames;
  25. /**
  26. * A class to modify a classloader to
  27. * support BSF language support.
  28. */
  29. public class ScriptFixBSFPath {
  30. private static final String UTIL_OPTIONAL_PACKAGE
  31. = MagicNames.ANT_CORE_PACKAGE + ".util.optional";
  32. private static final String BSF_PACKAGE = "org.apache.bsf";
  33. private static final String BSF_MANAGER = BSF_PACKAGE + ".BSFManager";
  34. private static final String BSF_SCRIPT_RUNNER
  35. = UTIL_OPTIONAL_PACKAGE + ".ScriptRunner";
  36. /**
  37. * The following are languages that have
  38. * scripting engines embedded in bsf.jar.
  39. * The array is converted to a map of
  40. * languagename->classname.
  41. */
  42. private static final String[] BSF_LANGUAGES =
  43. new String[] {
  44. "js", "org.mozilla.javascript.Scriptable",
  45. "javascript", "org.mozilla.javascript.Scriptable",
  46. "jacl", "tcl.lang.Interp",
  47. "netrexx", "netrexx.lang.Rexx",
  48. "nrx", "netrexx.lang.Rexx",
  49. "jython", "org.python.core.Py",
  50. "py", "org.python.core.Py",
  51. "xslt", "org.apache.xpath.objects.XObject"};
  52. /** A map of languages for which the engine in located in bsf */
  53. private static final Map<String, String> BSF_LANGUAGE_MAP = new HashMap<>();
  54. static {
  55. for (int i = 0; i < BSF_LANGUAGES.length; i += 2) {
  56. BSF_LANGUAGE_MAP.put(BSF_LANGUAGES[i], BSF_LANGUAGES[i + 1]);
  57. }
  58. }
  59. private File getClassSource(ClassLoader loader, String className) {
  60. return LoaderUtils.getResourceSource(
  61. loader,
  62. LoaderUtils.classNameToResource(className));
  63. }
  64. private File getClassSource(String className) {
  65. return getClassSource(getClass().getClassLoader(), className);
  66. }
  67. /**
  68. * Check if need to mess about with the classloader.
  69. * The class loader will need to be modified for two
  70. * reasons:
  71. * <ol>
  72. * <li>language is at a higher level than bsf for engines in bsf,
  73. * move bsf.
  74. * </li>
  75. * <li>bsf is at a higher level than oata.util.optional.ScriptRunner
  76. * </li>
  77. * </ol>
  78. *
  79. * Assume a simple model for the loader:
  80. * thisloader&lt;-customloader
  81. * or
  82. * thisloader
  83. *
  84. * @param loader the classloader to fix.
  85. * @param language the language to use.
  86. */
  87. public void fixClassLoader(ClassLoader loader, String language) {
  88. if (loader == getClass().getClassLoader()
  89. || !(loader instanceof AntClassLoader)) {
  90. return;
  91. }
  92. ClassLoader myLoader = getClass().getClassLoader();
  93. AntClassLoader fixLoader = (AntClassLoader) loader;
  94. // Check for location of bsf in this classloader
  95. File bsfSource = getClassSource(BSF_MANAGER);
  96. // If bsf is not in the classloader for this, need to move
  97. // runner.
  98. boolean needMoveRunner = (bsfSource == null);
  99. // Check for location of language
  100. String languageClassName = BSF_LANGUAGE_MAP.get(language);
  101. // Check if need to need to move bsf
  102. boolean needMoveBsf =
  103. bsfSource != null
  104. && languageClassName != null
  105. && !LoaderUtils.classExists(myLoader, languageClassName)
  106. && LoaderUtils.classExists(loader, languageClassName);
  107. // Update need to move runner
  108. needMoveRunner = needMoveRunner || needMoveBsf;
  109. // Check if bsf in place
  110. if (bsfSource == null) {
  111. bsfSource = getClassSource(loader, BSF_MANAGER);
  112. }
  113. if (bsfSource == null) {
  114. throw new BuildException(
  115. "Unable to find BSF classes for scripting");
  116. }
  117. if (needMoveBsf) {
  118. fixLoader.addPathComponent(bsfSource);
  119. fixLoader.addLoaderPackageRoot(BSF_PACKAGE);
  120. }
  121. if (needMoveRunner) {
  122. fixLoader.addPathComponent(
  123. LoaderUtils.getResourceSource(
  124. fixLoader,
  125. LoaderUtils.classNameToResource(BSF_SCRIPT_RUNNER)));
  126. fixLoader.addLoaderPackageRoot(UTIL_OPTIONAL_PACKAGE);
  127. }
  128. }
  129. }