1
17
18package org.tp23.antinstaller.antmod;
19
20import java.io.File;
21import java.io.FileInputStream;
22import java.io.FileNotFoundException;
23import java.io.IOException;
24import java.io.InputStream;
25import java.io.UnsupportedEncodingException;
26import java.net.URL;
27import java.util.Hashtable;
28import java.util.Stack;
29
30import org.apache.tools.ant.BuildException;
31import org.apache.tools.ant.Location;
32import org.apache.tools.ant.Project;
33import org.apache.tools.ant.ProjectHelper;
34import org.apache.tools.ant.RuntimeConfigurable;
35import org.apache.tools.ant.Target;
36import org.apache.tools.ant.Task;
37import org.apache.tools.ant.UnknownElement;
38import org.apache.tools.ant.helper.AntXMLContext;
39import org.apache.tools.ant.util.FileUtils;
40import org.apache.tools.ant.util.JAXPUtils;
41import org.xml.sax.Attributes;
42import org.xml.sax.InputSource;
43import org.xml.sax.Locator;
44import org.xml.sax.SAXException;
45import org.xml.sax.SAXParseException;
46import org.xml.sax.XMLReader;
47import org.xml.sax.helpers.DefaultHandler;
48
49
55public class ProjectHelper3 extends ProjectHelper {
56
57
58 private static AntHandler elementHandler = new ElementHandler();
60 private static AntHandler targetHandler = new TargetHandler();
61 private static AntHandler mainHandler = new MainHandler();
62 private static AntHandler projectHandler = new ProjectHandler();
63
64
67 private static FileUtils fu = FileUtils.newFileUtils();
68
69
77 public UnknownElement parseUnknownElement(Project project, URL source)
78 throws BuildException {
79 Target dummyTarget = new Target();
80 dummyTarget.setProject(project);
81
82 AntXMLContext context = new AntXMLContext(project);
83 context.addTarget(dummyTarget);
84 context.setImplicitTarget(dummyTarget);
85
86 parse(context.getProject(), source,
87 new RootHandler(context, elementHandler));
88 Task[] tasks = dummyTarget.getTasks();
89 if (tasks.length != 1) {
90 throw new BuildException("No tasks defined");
91 }
92 return (UnknownElement) tasks[0];
93 }
94
01 public void parse(Project project, Object source)
02 throws BuildException {
03 getImportStack().addElement(source);
04 AntXMLContext context = null;
06 context = (AntXMLContext) project.getReference("ant.parsing.context");
07 if (context == null) {
10 context = new AntXMLContext(project);
11 project.addReference("ant.parsing.context", context);
12 project.addReference("ant.targets", context.getTargets());
13 }
14
15 if (getImportStack().size() > 1) {
16 context.setIgnoreProjectTag(true);
18 Target currentTarget = context.getCurrentTarget();
19 try {
20 Target newCurrent = new Target();
21 newCurrent.setProject(project);
22 newCurrent.setName("");
23 context.setCurrentTarget(newCurrent);
24 parse(project, source, new RootHandler(context, mainHandler));
25 newCurrent.execute();
26 } finally {
27 context.setCurrentTarget(currentTarget);
28 }
29 } else {
30 parse(project, source, new RootHandler(context, mainHandler));
32 context.getImplicitTarget().execute();
34 }
35 }
36
37
46 public void parse(Project project, Object source, RootHandler handler)
47 throws BuildException {
48
49 AntXMLContext context = handler.context;
50
51 File buildFile = null;
52 URL url = null;
53 String buildFileName = null;
54
55 if (source instanceof File) {
56 buildFile = (File) source;
57 buildFile = fu.normalize(buildFile.getAbsolutePath());
58 context.setBuildFile(buildFile);
59 buildFileName = buildFile.toString();
60 } else if (source instanceof URL) {
62 url = (URL) source;
71 buildFileName = url.toString();
72 } else {
74 throw new BuildException("Source " + source.getClass().getName()
75 + " not supported by this plugin");
76 }
77
78 InputStream inputStream = null;
79 InputSource inputSource = null;
80
81
82 try {
83
86 XMLReader parser = JAXPUtils.getNamespaceXMLReader();
87
88 String uri = null;
89 if (buildFile != null) {
90 uri = fu.toURI(buildFile.getAbsolutePath());
91 inputStream = new FileInputStream(buildFile);
92 } else {
93 inputStream = url.openStream();
94 uri = url.toString(); }
96
97 inputSource = new InputSource(inputStream);
98 if (uri != null) {
99 inputSource.setSystemId(uri);
00 }
01 project.log("parsing buildfile " + buildFileName
02 + " with URI = " + uri, Project.MSG_VERBOSE);
03
04 DefaultHandler hb = handler;
05
06 parser.setContentHandler(hb);
07 parser.setEntityResolver(hb);
08 parser.setErrorHandler(hb);
09 parser.setDTDHandler(hb);
10 parser.parse(inputSource);
11 } catch (SAXParseException exc) {
12 Location location = new Location(exc.getSystemId(),
13 exc.getLineNumber(), exc.getColumnNumber());
14
15 Throwable t = exc.getException();
16 if (t instanceof BuildException) {
17 BuildException be = (BuildException) t;
18 if (be.getLocation() == Location.UNKNOWN_LOCATION) {
19 be.setLocation(location);
20 }
21 throw be;
22 }
23
24 throw new BuildException(exc.getMessage(), t, location);
25 } catch (SAXException exc) {
26 Throwable t = exc.getException();
27 if (t instanceof BuildException) {
28 throw (BuildException) t;
29 }
30 throw new BuildException(exc.getMessage(), t);
31 } catch (FileNotFoundException exc) {
32 throw new BuildException(exc);
33 } catch (UnsupportedEncodingException exc) {
34 throw new BuildException("Encoding of project file "
35 + buildFileName + " is invalid.",
36 exc);
37 } catch (IOException exc) {
38 throw new BuildException("Error reading project file "
39 + buildFileName + ": " + exc.getMessage(),
40 exc);
41 } finally {
42 if (inputStream != null) {
43 try {
44 inputStream.close();
45 } catch (IOException ioe) {
46 }
48 }
49 }
50 }
51
52
60 public static class AntHandler {
61
76 public void onStartElement(String uri, String tag, String qname,
77 Attributes attrs,
78 AntXMLContext context)
79 throws SAXParseException {
80 }
81
82
99 public AntHandler onStartChild(String uri, String tag, String qname,
00 Attributes attrs,
01 AntXMLContext context)
02 throws SAXParseException {
03 throw new SAXParseException("Unexpected element \"" + qname
04 + " \"", context.getLocator());
05 }
06
07
16 public void onEndChild(String uri, String tag, String qname,
17 AntXMLContext context)
18 throws SAXParseException {
19 }
20
21
28 public void onEndElement(String uri, String tag,
29 AntXMLContext context) {
30 }
31
32
45 public void characters(char[] buf, int start, int count, AntXMLContext context)
46 throws SAXParseException {
47 String s = new String(buf, start, count).trim();
48
49 if (s.length() > 0) {
50 throw new SAXParseException("Unexpected text \"" + s
51 + "\"", context.getLocator());
52 }
53 }
54
55
61 protected void checkNamespace(String uri) {
62
63 }
64 }
65
66
71 public static class RootHandler extends DefaultHandler {
72 private Stack antHandlers = new Stack();
73 private AntHandler currentHandler = null;
74 private AntXMLContext context;
75
76
82 public RootHandler(AntXMLContext context, AntHandler rootHandler) {
83 currentHandler = rootHandler;
84 antHandlers.push(currentHandler);
85 this.context = context;
86 }
87
88
92 public AntHandler getCurrentAntHandler() {
93 return currentHandler;
94 }
95
96
06 public InputSource resolveEntity(String publicId,
07 String systemId) {
08
09 context.getProject().log("resolving systemId: "
10 + systemId, Project.MSG_VERBOSE);
11
12 if (systemId.startsWith("file:")) {
13 String path = fu.fromURI(systemId);
14
15 File file = new File(path);
16 if (!file.isAbsolute()) {
17 file = fu.resolveFile(context.getBuildFileParent(), path);
18 }
19 try {
20 InputSource inputSource =
21 new InputSource(new FileInputStream(file));
22 inputSource.setSystemId(fu.toURI(file.getAbsolutePath()));
23 return inputSource;
24 } catch (FileNotFoundException fne) {
25 context.getProject().log(file.getAbsolutePath()
26 + " could not be found", Project.MSG_WARN);
27 }
28
29 }
30 return null;
32 }
33
34
48 public void startElement(String uri, String tag, String qname, Attributes attrs)
49 throws SAXParseException {
50 AntHandler next
51 = currentHandler.onStartChild(uri, tag, qname, attrs, context);
52 antHandlers.push(currentHandler);
53 currentHandler = next;
54 currentHandler.onStartElement(uri, tag, qname, attrs, context);
55 }
56
57
63 public void setDocumentLocator(Locator locator) {
64 context.setLocator(locator);
65 }
66
67
81 public void endElement(String uri, String name, String qName) throws SAXException {
82 currentHandler.onEndElement(uri, name, context);
83 AntHandler prev = (AntHandler) antHandlers.pop();
84 currentHandler = prev;
85 if (currentHandler != null) {
86 currentHandler.onEndChild(uri, name, qName, context);
87 }
88 }
89
90
98 public void characters(char[] buf, int start, int count)
99 throws SAXParseException {
00 currentHandler.characters(buf, start, count, context);
01 }
02
03
09 public void startPrefixMapping(String prefix, String uri) {
10 context.startPrefixMapping(prefix, uri);
11 }
12
13
18 public void endPrefixMapping(String prefix) {
19 context.endPrefixMapping(prefix);
20 }
21 }
22
23
28 public static class MainHandler extends AntHandler {
29
30
41 public AntHandler onStartChild(String uri, String name, String qname,
42 Attributes attrs,
43 AntXMLContext context)
44 throws SAXParseException {
45 if (name.equals("project")
46 && (uri.equals("") || uri.equals(ANT_CORE_URI))) {
47 return ProjectHelper3.projectHandler;
48 } else {
49 throw new SAXParseException("Unexpected element \"" + qname
55 + "\" " + name, context.getLocator());
56 }
57 }
58 }
59
60
63 public static class ProjectHandler extends AntHandler {
64
65
84 public void onStartElement(String uri, String tag, String qname,
85 Attributes attrs,
86 AntXMLContext context)
87 throws SAXParseException {
88 String id = null;
89 String baseDir = null;
90 boolean nameAttributeSet = false;
91
92 Project project = context.getProject();
93
94
04
05 for (int i = 0; i < attrs.getLength(); i++) {
06 String attrUri = attrs.getURI(i);
07 if (attrUri != null
08 && !attrUri.equals("")
09 && !attrUri.equals(uri)) {
10 continue; }
12 String key = attrs.getLocalName(i);
13 String value = attrs.getValue(i);
14
15 if (key.equals("default")) {
16 if (value != null && !value.equals("")) {
17 if (!context.isIgnoringProjectTag()) {
18 project.setDefault(value);
19 }
20 }
21 } else if (key.equals("name")) {
22 if (value != null) {
23 context.setCurrentProjectName(value);
24 nameAttributeSet = true;
25 if (!context.isIgnoringProjectTag()) {
26 project.setName(value);
27 project.addReference(value, project);
28 }
29 }
30 } else if (key.equals("id")) {
31 if (value != null) {
32 if (!context.isIgnoringProjectTag()) {
34 project.addReference(value, project);
35 }
36 }
37 } else if (key.equals("basedir")) {
38 if (!context.isIgnoringProjectTag()) {
39 baseDir = value;
40 }
41 } else {
42 throw new SAXParseException("Unexpected attribute \""
44 + attrs.getQName(i) + "\"", context.getLocator());
45 }
46 }
47
48 String antFileProp = "ant.file." + context.getCurrentProjectName();
50 String dup = project.getProperty(antFileProp);
51 if (dup != null && nameAttributeSet) {
52 File dupFile = new File(dup);
53 if (context.isIgnoringProjectTag()
54 && !dupFile.equals(context.getBuildFile())) {
55 project.log("Duplicated project name in import. Project "
56 + context.getCurrentProjectName() + " defined first in "
57 + dup + " and again in " + context.getBuildFile(),
58 Project.MSG_WARN);
59 }
60 }
61
62 if (context.getBuildFile() != null) {
63 project.setUserProperty("ant.file."
64 + context.getCurrentProjectName(),
65 context.getBuildFile().toString());
66 }
67
68 if (context.isIgnoringProjectTag()) {
69 return;
71 }
72 if (project.getProperty("basedir") != null) {
74 project.setBasedir(project.getProperty("basedir"));
75 } else {
76 if (baseDir == null) {
78 project.setBasedir(context.getBuildFileParent().getAbsolutePath());
79 } else {
80 if ((new File(baseDir)).isAbsolute()) {
82 project.setBasedir(baseDir);
83 } else {
84 project.setBaseDir(fu.resolveFile(
85 context.getBuildFileParent(), baseDir));
86 }
87 }
88 }
89
90 project.addTarget("", context.getImplicitTarget());
91 context.setCurrentTarget(context.getImplicitTarget());
92 }
93
94
13 public AntHandler onStartChild(String uri, String name, String qname,
14 Attributes attrs,
15 AntXMLContext context)
16 throws SAXParseException {
17 if (name.equals("target")
18 && (uri.equals("") || uri.equals(ANT_CORE_URI))) {
19 return ProjectHelper3.targetHandler;
20 } else {
21 return ProjectHelper3.elementHandler;
22 }
23 }
24
25 }
26
27
30 public static class TargetHandler extends AntHandler {
31
32
52 public void onStartElement(String uri, String tag, String qname,
53 Attributes attrs,
54 AntXMLContext context)
55 throws SAXParseException {
56 String name = null;
57 String depends = "";
58
59 Project project = context.getProject();
60 Target target = new Target();
61 target.setProject(project);
62 context.addTarget(target);
63
64 for (int i = 0; i < attrs.getLength(); i++) {
65 String attrUri = attrs.getURI(i);
66 if (attrUri != null
67 && !attrUri.equals("")
68 && !attrUri.equals(uri)) {
69 continue; }
71 String key = attrs.getLocalName(i);
72 String value = attrs.getValue(i);
73
74 if (key.equals("name")) {
75 name = value;
76 if ("".equals(name)) {
77 throw new BuildException("name attribute must "
78 + "not be empty");
79 }
80 } else if (key.equals("depends")) {
81 depends = value;
82 } else if (key.equals("if")) {
83 target.setIf(value);
84 } else if (key.equals("unless")) {
85 target.setUnless(value);
86 } else if (key.equals("id")) {
87 if (value != null && !value.equals("")) {
88 context.getProject().addReference(value, target);
89 }
90 } else if (key.equals("description")) {
91 target.setDescription(value);
92 } else {
93 throw new SAXParseException("Unexpected attribute \""
94 + key + "\"", context.getLocator());
95 }
96 }
97
98 if (name == null) {
99 throw new SAXParseException("target element appears without "
00 + "a name attribute", context.getLocator());
01 }
02
03 Hashtable currentTargets = project.getTargets();
04
05 if (currentTargets.containsKey(name)) {
07 if (!context.isIgnoringProjectTag()) {
08 throw new BuildException(
10 "Duplicate target '" + name + "'",
11 new Location(context.getLocator().getSystemId(),
12 context.getLocator().getLineNumber(),
13 context.getLocator().getColumnNumber()));
14 }
15 if (context.getCurrentProjectName() != null) {
17 String newName = context.getCurrentProjectName()
18 + "." + name;
19 project.log("Already defined in main or a previous import, "
20 + "define " + name + " as " + newName,
21 Project.MSG_VERBOSE);
22 name = newName;
23 } else {
24 project.log("Already defined in main or a previous import, "
25 + "ignore " + name, Project.MSG_VERBOSE);
26 name = null;
27 }
28 }
29
30 if (name != null) {
31 target.setName(name);
32 project.addOrReplaceTarget(name, target);
33 }
34
35 if (depends.length() > 0) {
37 target.setDepends(depends);
38 }
39 }
40
41
56 public AntHandler onStartChild(String uri, String name, String qname,
57 Attributes attrs,
58 AntXMLContext context)
59 throws SAXParseException {
60 return ProjectHelper3.elementHandler;
61 }
62
63
71 public void onEndElement(String uri, String tag, AntXMLContext context) {
72 context.setCurrentTarget(context.getImplicitTarget());
73 }
74 }
75
76
79 public static class ElementHandler extends AntHandler {
80
81
84 public ElementHandler() {
85 }
86
87
05 public void onStartElement(String uri, String tag, String qname,
06 Attributes attrs,
07 AntXMLContext context)
08 throws SAXParseException {
09 RuntimeConfigurable parentWrapper = context.currentWrapper();
10 Object parent = null;
11
12 if (parentWrapper != null) {
13 parent = parentWrapper.getProxy();
14 }
15
16
18 UnknownElement task = new UnknownElement(tag);
19 task.setProject(context.getProject());
20 task.setNamespace(uri);
21 task.setQName(qname);
22 task.setTaskType(
23 ProjectHelper.genComponentName(task.getNamespace(), tag));
24 task.setTaskName(qname);
25
26 Location location = new Location(context.getLocator().getSystemId(),
27 context.getLocator().getLineNumber(),
28 context.getLocator().getColumnNumber());
29 task.setLocation(location);
30 task.setOwningTarget(context.getCurrentTarget());
31
32 context.configureId(task, attrs);
33
34 if (parent != null) {
35 ((UnknownElement) parent).addChild(task);
37 } else {
38 context.getCurrentTarget().addTask(task);
40 }
41
42
45 RuntimeConfigurable wrapper
46 = new RuntimeConfigurable(task, task.getTaskName());
47
48 for (int i = 0; i < attrs.getLength(); i++) {
49 String name = attrs.getLocalName(i);
50 String attrUri = attrs.getURI(i);
51 if (attrUri != null
52 && !attrUri.equals("")
53 && !attrUri.equals(uri)) {
54 name = attrUri + ":" + attrs.getQName(i);
55 }
56 String value = attrs.getValue(i);
57 if (ANT_TYPE.equals(name)
62 || (ANT_CORE_URI.equals(attrUri)
63 && ANT_TYPE.equals(attrs.getLocalName(i)))) {
64 name = ANT_TYPE;
65 int index = value.indexOf(":");
66 if (index != -1) {
67 String prefix = value.substring(0, index);
68 String mappedUri = context.getPrefixMapping(prefix);
69 if (mappedUri == null) {
70 throw new BuildException(
71 "Unable to find XML NS prefix " + prefix);
72 }
73 value = ProjectHelper.genComponentName(
74 mappedUri, value.substring(index + 1));
75 }
76 }
77 wrapper.setAttribute(name, value);
78 }
79
80 if (parentWrapper != null) {
81 parentWrapper.addChild(wrapper);
82 }
83
84 context.pushWrapper(wrapper);
85 }
86
87
00 public void characters(char[] buf, int start, int count,
01 AntXMLContext context)
02 throws SAXParseException {
03 RuntimeConfigurable wrapper = context.currentWrapper();
04 wrapper.addText(buf, start, count);
05 }
06
07
24 public AntHandler onStartChild(String uri, String tag, String qname,
25 Attributes attrs,
26 AntXMLContext context)
27 throws SAXParseException {
28 return ProjectHelper3.elementHandler;
29 }
30
31
39 public void onEndElement(String uri, String tag, AntXMLContext context) {
40 context.popWrapper();
41 }
42 }
43}
44