1. /*
  2. * Copyright 2003-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. */
  17. package org.apache.tools.ant.helper;
  18. import java.io.File;
  19. import java.util.ArrayList;
  20. import java.util.HashMap;
  21. import java.util.List;
  22. import java.util.Map;
  23. import java.util.Vector;
  24. import org.xml.sax.Locator;
  25. import org.xml.sax.Attributes;
  26. import org.apache.tools.ant.Project;
  27. import org.apache.tools.ant.Target;
  28. import org.apache.tools.ant.RuntimeConfigurable;
  29. /**
  30. * Context information for the ant processing.
  31. *
  32. */
  33. public class AntXMLContext {
  34. /** The project to configure. */
  35. private Project project;
  36. /** The configuration file to parse. */
  37. private File buildFile;
  38. /** Vector with all the targets, in the order they are
  39. * defined. Project maintains a Hashtable, which is not ordered.
  40. * This will allow description to know the original order.
  41. */
  42. private Vector targetVector = new Vector();
  43. /**
  44. * Parent directory of the build file. Used for resolving entities
  45. * and setting the project's base directory.
  46. */
  47. private File buildFileParent;
  48. /** Name of the current project */
  49. private String currentProjectName;
  50. /**
  51. * Locator for the configuration file parser.
  52. * Used for giving locations of errors etc.
  53. */
  54. private Locator locator;
  55. /**
  56. * Target that all other targets will depend upon implicitly.
  57. *
  58. * <p>This holds all tasks and data type definitions that have
  59. * been placed outside of targets.</p>
  60. */
  61. private Target implicitTarget = new Target();
  62. /** Current target ( no need for a stack as the processing model
  63. allows only one level of target ) */
  64. private Target currentTarget = null;
  65. /** The stack of RuntimeConfigurable2 wrapping the
  66. objects.
  67. */
  68. private Vector wStack = new Vector();
  69. /**
  70. * Indicates whether the project tag attributes are to be ignored
  71. * when processing a particular build file.
  72. */
  73. private boolean ignoreProjectTag = false;
  74. /** Keeps track of prefix -> uri mapping during parsing */
  75. private Map prefixMapping = new HashMap();
  76. /**
  77. * constructor
  78. * @param project the project to which this antxml context belongs to
  79. */
  80. public AntXMLContext(Project project) {
  81. this.project = project;
  82. implicitTarget.setProject(project);
  83. implicitTarget.setName("");
  84. targetVector.addElement(implicitTarget);
  85. }
  86. /**
  87. * sets the build file to which the XML context belongs
  88. * @param buildFile ant build file
  89. */
  90. public void setBuildFile(File buildFile) {
  91. this.buildFile = buildFile;
  92. this.buildFileParent = new File(buildFile.getParent());
  93. }
  94. /**
  95. * find out the build file
  96. * @return the build file to which the xml context belongs
  97. */
  98. public File getBuildFile() {
  99. return buildFile;
  100. }
  101. /**
  102. * find out the parent build file of this build file
  103. * @return the parent build file of this build file
  104. */
  105. public File getBuildFileParent() {
  106. return buildFileParent;
  107. }
  108. /**
  109. * find out the project to which this antxml context belongs
  110. * @return project
  111. */
  112. public Project getProject() {
  113. return project;
  114. }
  115. /**
  116. * find out the current project name
  117. * @return current project name
  118. */
  119. public String getCurrentProjectName() {
  120. return currentProjectName;
  121. }
  122. /**
  123. * set the name of the current project
  124. * @param name name of the current project
  125. */
  126. public void setCurrentProjectName(String name) {
  127. this.currentProjectName = name;
  128. }
  129. /**
  130. * get the current runtime configurable wrapper
  131. * can return null
  132. * @return runtime configurable wrapper
  133. */
  134. public RuntimeConfigurable currentWrapper() {
  135. if (wStack.size() < 1) {
  136. return null;
  137. }
  138. return (RuntimeConfigurable) wStack.elementAt(wStack.size() - 1);
  139. }
  140. /**
  141. * get the runtime configurable wrapper of the parent project
  142. * can return null
  143. * @return runtime configurable wrapper of the parent project
  144. */
  145. public RuntimeConfigurable parentWrapper() {
  146. if (wStack.size() < 2) {
  147. return null;
  148. }
  149. return (RuntimeConfigurable) wStack.elementAt(wStack.size() - 2);
  150. }
  151. /**
  152. * add a runtime configurable wrapper to the internal stack
  153. * @param wrapper runtime configurable wrapper
  154. */
  155. public void pushWrapper(RuntimeConfigurable wrapper) {
  156. wStack.addElement(wrapper);
  157. }
  158. /**
  159. * remove a runtime configurable wrapper from the stack
  160. */
  161. public void popWrapper() {
  162. if (wStack.size() > 0) {
  163. wStack.removeElementAt(wStack.size() - 1);
  164. }
  165. }
  166. /**
  167. * access the stack of wrappers
  168. * @return the stack of wrappers
  169. */
  170. public Vector getWrapperStack() {
  171. return wStack;
  172. }
  173. /**
  174. * add a new target
  175. * @param target target to add
  176. */
  177. public void addTarget(Target target) {
  178. targetVector.addElement(target);
  179. currentTarget = target;
  180. }
  181. /**
  182. * get the current target
  183. * @return current target
  184. */
  185. public Target getCurrentTarget() {
  186. return currentTarget;
  187. }
  188. /**
  189. * get the implicit target
  190. * @return implicit target
  191. */
  192. public Target getImplicitTarget() {
  193. return implicitTarget;
  194. }
  195. /**
  196. * sets the current target
  197. * @param target current target
  198. */
  199. public void setCurrentTarget(Target target) {
  200. this.currentTarget = target;
  201. }
  202. /**
  203. * sets the implicit target
  204. * @param target the implicit target
  205. */
  206. public void setImplicitTarget(Target target) {
  207. this.implicitTarget = target;
  208. }
  209. /**
  210. * access the vector of targets
  211. * @return vector of targets
  212. */
  213. public Vector getTargets() {
  214. return targetVector;
  215. }
  216. /**
  217. * Scans an attribute list for the <code>id</code> attribute and
  218. * stores a reference to the target object in the project if an
  219. * id is found.
  220. * <p>
  221. * This method was moved out of the configure method to allow
  222. * it to be executed at parse time.
  223. * @param element the current element
  224. * @param attr attributes of the current element
  225. */
  226. public void configureId(Object element, Attributes attr) {
  227. String id = attr.getValue("id");
  228. if (id != null) {
  229. project.addReference(id, element);
  230. }
  231. }
  232. /**
  233. * access the locator
  234. * @return locator
  235. */
  236. public Locator getLocator() {
  237. return locator;
  238. }
  239. /**
  240. * sets the locator
  241. * @param locator locator
  242. */
  243. public void setLocator(Locator locator) {
  244. this.locator = locator;
  245. }
  246. /**
  247. * tells whether the project tag is being ignored
  248. * @return whether the project tag is being ignored
  249. */
  250. public boolean isIgnoringProjectTag() {
  251. return ignoreProjectTag;
  252. }
  253. /**
  254. * sets the flag to ignore the project tag
  255. * @param flag to ignore the project tag
  256. */
  257. public void setIgnoreProjectTag(boolean flag) {
  258. this.ignoreProjectTag = flag;
  259. }
  260. /**
  261. * Called during parsing, stores the prefix to uri mapping.
  262. *
  263. * @param prefix a namespace prefix
  264. * @param uri a namespace uri
  265. */
  266. public void startPrefixMapping(String prefix, String uri) {
  267. List list = (List) prefixMapping.get(prefix);
  268. if (list == null) {
  269. list = new ArrayList();
  270. prefixMapping.put(prefix, list);
  271. }
  272. list.add(uri);
  273. }
  274. /**
  275. * End of prefix to uri mapping.
  276. *
  277. * @param prefix the namespace prefix
  278. */
  279. public void endPrefixMapping(String prefix) {
  280. List list = (List) prefixMapping.get(prefix);
  281. if (list == null || list.size() == 0) {
  282. return; // Should not happen
  283. }
  284. list.remove(list.size() - 1);
  285. }
  286. /**
  287. * prefix to namespace uri mapping
  288. *
  289. * @param prefix the prefix to map
  290. * @return the uri for this prefix, null if not present
  291. */
  292. public String getPrefixMapping(String prefix) {
  293. List list = (List) prefixMapping.get(prefix);
  294. if (list == null || list.size() == 0) {
  295. return null;
  296. }
  297. return (String) list.get(list.size() - 1);
  298. }
  299. }