001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018: package org.apache.tools.ant.helper;
019:
020: import java.io.File;
021: import java.util.ArrayList;
022: import java.util.HashMap;
023: import java.util.List;
024: import java.util.Map;
025: import java.util.Vector;
026:
027: import org.xml.sax.Locator;
028: import org.xml.sax.Attributes;
029:
030: import org.apache.tools.ant.Project;
031: import org.apache.tools.ant.Target;
032: import org.apache.tools.ant.Location;
033: import org.apache.tools.ant.RuntimeConfigurable;
034:
035: /**
036: * Context information for the ant processing.
037: *
038: */
039: public class AntXMLContext {
040: /** The project to configure. */
041: private Project project;
042:
043: /** The configuration file to parse. */
044: private File buildFile;
045:
046: /** Vector with all the targets, in the order they are
047: * defined. Project maintains a Hashtable, which is not ordered.
048: * This will allow description to know the original order.
049: */
050: private Vector targetVector = new Vector();
051:
052: /**
053: * Parent directory of the build file. Used for resolving entities
054: * and setting the project's base directory.
055: */
056: private File buildFileParent;
057:
058: /** Name of the current project */
059: private String currentProjectName;
060:
061: /**
062: * Locator for the configuration file parser.
063: * Used for giving locations of errors etc.
064: */
065: private Locator locator;
066:
067: /**
068: * Target that all other targets will depend upon implicitly.
069: *
070: * <p>This holds all tasks and data type definitions that have
071: * been placed outside of targets.</p>
072: */
073: private Target implicitTarget = new Target();
074:
075: /** Current target ( no need for a stack as the processing model
076: allows only one level of target ) */
077: private Target currentTarget = null;
078:
079: /** The stack of RuntimeConfigurable2 wrapping the
080: objects.
081: */
082: private Vector wStack = new Vector();
083:
084: /**
085: * Indicates whether the project tag attributes are to be ignored
086: * when processing a particular build file.
087: */
088: private boolean ignoreProjectTag = false;
089:
090: /** Keeps track of prefix -> uri mapping during parsing */
091: private Map prefixMapping = new HashMap();
092:
093: /** Keeps track of targets in files */
094: private Map currentTargets = null;
095:
096: /**
097: * constructor
098: * @param project the project to which this antxml context belongs to
099: */
100: public AntXMLContext(Project project) {
101: this .project = project;
102: implicitTarget.setProject(project);
103: implicitTarget.setName("");
104: targetVector.addElement(implicitTarget);
105: }
106:
107: /**
108: * sets the build file to which the XML context belongs
109: * @param buildFile ant build file
110: */
111: public void setBuildFile(File buildFile) {
112: this .buildFile = buildFile;
113: this .buildFileParent = new File(buildFile.getParent());
114: implicitTarget.setLocation(new Location(buildFile
115: .getAbsolutePath()));
116: }
117:
118: /**
119: * find out the build file
120: * @return the build file to which the xml context belongs
121: */
122: public File getBuildFile() {
123: return buildFile;
124: }
125:
126: /**
127: * find out the parent build file of this build file
128: * @return the parent build file of this build file
129: */
130: public File getBuildFileParent() {
131: return buildFileParent;
132: }
133:
134: /**
135: * find out the project to which this antxml context belongs
136: * @return project
137: */
138: public Project getProject() {
139: return project;
140: }
141:
142: /**
143: * find out the current project name
144: * @return current project name
145: */
146: public String getCurrentProjectName() {
147: return currentProjectName;
148: }
149:
150: /**
151: * set the name of the current project
152: * @param name name of the current project
153: */
154: public void setCurrentProjectName(String name) {
155: this .currentProjectName = name;
156: }
157:
158: /**
159: * get the current runtime configurable wrapper
160: * can return null
161: * @return runtime configurable wrapper
162: */
163: public RuntimeConfigurable currentWrapper() {
164: if (wStack.size() < 1) {
165: return null;
166: }
167: return (RuntimeConfigurable) wStack
168: .elementAt(wStack.size() - 1);
169: }
170:
171: /**
172: * get the runtime configurable wrapper of the parent project
173: * can return null
174: * @return runtime configurable wrapper of the parent project
175: */
176: public RuntimeConfigurable parentWrapper() {
177: if (wStack.size() < 2) {
178: return null;
179: }
180: return (RuntimeConfigurable) wStack
181: .elementAt(wStack.size() - 2);
182: }
183:
184: /**
185: * add a runtime configurable wrapper to the internal stack
186: * @param wrapper runtime configurable wrapper
187: */
188: public void pushWrapper(RuntimeConfigurable wrapper) {
189: wStack.addElement(wrapper);
190: }
191:
192: /**
193: * remove a runtime configurable wrapper from the stack
194: */
195: public void popWrapper() {
196: if (wStack.size() > 0) {
197: wStack.removeElementAt(wStack.size() - 1);
198: }
199: }
200:
201: /**
202: * access the stack of wrappers
203: * @return the stack of wrappers
204: */
205: public Vector getWrapperStack() {
206: return wStack;
207: }
208:
209: /**
210: * add a new target
211: * @param target target to add
212: */
213: public void addTarget(Target target) {
214: targetVector.addElement(target);
215: currentTarget = target;
216: }
217:
218: /**
219: * get the current target
220: * @return current target
221: */
222: public Target getCurrentTarget() {
223: return currentTarget;
224: }
225:
226: /**
227: * get the implicit target
228: * @return implicit target
229: */
230: public Target getImplicitTarget() {
231: return implicitTarget;
232: }
233:
234: /**
235: * sets the current target
236: * @param target current target
237: */
238: public void setCurrentTarget(Target target) {
239: this .currentTarget = target;
240: }
241:
242: /**
243: * sets the implicit target
244: * @param target the implicit target
245: */
246: public void setImplicitTarget(Target target) {
247: this .implicitTarget = target;
248: }
249:
250: /**
251: * access the vector of targets
252: * @return vector of targets
253: */
254: public Vector getTargets() {
255: return targetVector;
256: }
257:
258: /**
259: * Scans an attribute list for the <code>id</code> attribute and
260: * stores a reference to the target object in the project if an
261: * id is found.
262: * <p>
263: * This method was moved out of the configure method to allow
264: * it to be executed at parse time.
265: * @param element the current element
266: * @param attr attributes of the current element
267: */
268: public void configureId(Object element, Attributes attr) {
269: String id = attr.getValue("id");
270: if (id != null) {
271: project.addIdReference(id, element);
272: }
273: }
274:
275: /**
276: * access the locator
277: * @return locator
278: */
279: public Locator getLocator() {
280: return locator;
281: }
282:
283: /**
284: * sets the locator
285: * @param locator locator
286: */
287: public void setLocator(Locator locator) {
288: this .locator = locator;
289: }
290:
291: /**
292: * tells whether the project tag is being ignored
293: * @return whether the project tag is being ignored
294: */
295: public boolean isIgnoringProjectTag() {
296: return ignoreProjectTag;
297: }
298:
299: /**
300: * sets the flag to ignore the project tag
301: * @param flag to ignore the project tag
302: */
303: public void setIgnoreProjectTag(boolean flag) {
304: this .ignoreProjectTag = flag;
305: }
306:
307: /**
308: * Called during parsing, stores the prefix to uri mapping.
309: *
310: * @param prefix a namespace prefix
311: * @param uri a namespace uri
312: */
313: public void startPrefixMapping(String prefix, String uri) {
314: List list = (List) prefixMapping.get(prefix);
315: if (list == null) {
316: list = new ArrayList();
317: prefixMapping.put(prefix, list);
318: }
319: list.add(uri);
320: }
321:
322: /**
323: * End of prefix to uri mapping.
324: *
325: * @param prefix the namespace prefix
326: */
327: public void endPrefixMapping(String prefix) {
328: List list = (List) prefixMapping.get(prefix);
329: if (list == null || list.size() == 0) {
330: return; // Should not happen
331: }
332: list.remove(list.size() - 1);
333: }
334:
335: /**
336: * prefix to namespace uri mapping
337: *
338: * @param prefix the prefix to map
339: * @return the uri for this prefix, null if not present
340: */
341: public String getPrefixMapping(String prefix) {
342: List list = (List) prefixMapping.get(prefix);
343: if (list == null || list.size() == 0) {
344: return null;
345: }
346: return (String) list.get(list.size() - 1);
347: }
348:
349: /**
350: * Get the targets in the current source file.
351: * @return the current targets.
352: */
353: public Map getCurrentTargets() {
354: return currentTargets;
355: }
356:
357: /**
358: * Set the map of the targets in the current source file.
359: * @param currentTargets a map of targets.
360: */
361: public void setCurrentTargets(Map currentTargets) {
362: this.currentTargets = currentTargets;
363: }
364:
365: }
|