1 18 19 package org.apache.tools.ant.helper; 20 21 import org.apache.tools.ant.BuildException; 22 import org.apache.tools.ant.Location; 23 import org.apache.tools.ant.Project; 24 import org.apache.tools.ant.ProjectHelper; 25 import org.apache.tools.ant.RuntimeConfigurable; 26 import org.apache.tools.ant.Target; 27 import org.apache.tools.ant.Task; 28 import org.apache.tools.ant.UnknownElement; 29 import org.apache.tools.ant.util.FileUtils; 30 import org.apache.tools.ant.util.JAXPUtils; 31 import org.xml.sax.Attributes ; 32 import org.xml.sax.InputSource ; 33 import org.xml.sax.Locator ; 34 import org.xml.sax.SAXException ; 35 import org.xml.sax.SAXParseException ; 36 import org.xml.sax.XMLReader ; 37 import org.xml.sax.helpers.DefaultHandler ; 38 39 import java.io.File ; 40 import java.io.FileInputStream ; 41 import java.io.FileNotFoundException ; 42 import java.io.IOException ; 43 import java.io.InputStream ; 44 import java.io.UnsupportedEncodingException ; 45 import java.net.URL ; 46 import java.util.HashMap ; 47 import java.util.Hashtable ; 48 import java.util.Map ; 49 import java.util.Stack ; 50 51 55 public class ProjectHelper2 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 final FileUtils FILE_UTILS = FileUtils.getFileUtils(); 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 101 public void parse(Project project, Object source) 102 throws BuildException { 103 getImportStack().addElement(source); 104 AntXMLContext context = null; 106 context = (AntXMLContext) project.getReference("ant.parsing.context"); 107 if (context == null) { 110 context = new AntXMLContext(project); 111 project.addReference("ant.parsing.context", context); 112 project.addReference("ant.targets", context.getTargets()); 113 } 114 115 if (getImportStack().size() > 1) { 116 context.setIgnoreProjectTag(true); 118 Target currentTarget = context.getCurrentTarget(); 119 Target currentImplicit = context.getImplicitTarget(); 120 Map currentTargets = context.getCurrentTargets(); 121 try { 122 Target newCurrent = new Target(); 123 newCurrent.setProject(project); 124 newCurrent.setName(""); 125 context.setCurrentTarget(newCurrent); 126 context.setCurrentTargets(new HashMap ()); 127 context.setImplicitTarget(newCurrent); 128 parse(project, source, new RootHandler(context, mainHandler)); 129 newCurrent.execute(); 130 } finally { 131 context.setCurrentTarget(currentTarget); 132 context.setImplicitTarget(currentImplicit); 133 context.setCurrentTargets(currentTargets); 134 } 135 } else { 136 context.setCurrentTargets(new HashMap ()); 138 parse(project, source, new RootHandler(context, mainHandler)); 139 context.getImplicitTarget().execute(); 141 } 142 } 143 144 153 public void parse(Project project, Object source, RootHandler handler) 154 throws BuildException { 155 156 AntXMLContext context = handler.context; 157 158 File buildFile = null; 159 URL url = null; 160 String buildFileName = null; 161 162 if (source instanceof File ) { 163 buildFile = (File ) source; 164 buildFile = FILE_UTILS.normalize(buildFile.getAbsolutePath()); 165 context.setBuildFile(buildFile); 166 buildFileName = buildFile.toString(); 167 } else if (source instanceof URL ) { 169 url = (URL ) source; 170 buildFileName = url.toString(); 171 } else { 173 throw new BuildException("Source " + source.getClass().getName() 174 + " not supported by this plugin"); 175 } 176 177 InputStream inputStream = null; 178 InputSource inputSource = null; 179 180 181 try { 182 185 XMLReader parser = JAXPUtils.getNamespaceXMLReader(); 186 187 String uri = null; 188 if (buildFile != null) { 189 uri = FILE_UTILS.toURI(buildFile.getAbsolutePath()); 190 inputStream = new FileInputStream (buildFile); 191 } else { 192 inputStream = url.openStream(); 193 uri = url.toString(); } 195 196 inputSource = new InputSource (inputStream); 197 if (uri != null) { 198 inputSource.setSystemId(uri); 199 } 200 project.log("parsing buildfile " + buildFileName 201 + " with URI = " + uri, Project.MSG_VERBOSE); 202 203 DefaultHandler hb = handler; 204 205 parser.setContentHandler(hb); 206 parser.setEntityResolver(hb); 207 parser.setErrorHandler(hb); 208 parser.setDTDHandler(hb); 209 parser.parse(inputSource); 210 } catch (SAXParseException exc) { 211 Location location = new Location(exc.getSystemId(), 212 exc.getLineNumber(), exc.getColumnNumber()); 213 214 Throwable t = exc.getException(); 215 if (t instanceof BuildException) { 216 BuildException be = (BuildException) t; 217 if (be.getLocation() == Location.UNKNOWN_LOCATION) { 218 be.setLocation(location); 219 } 220 throw be; 221 } else if (t == null) { 222 t = exc; 223 } 224 225 throw new BuildException(exc.getMessage(), t, location); 226 } catch (SAXException exc) { 227 Throwable t = exc.getException(); 228 if (t instanceof BuildException) { 229 throw (BuildException) t; 230 } else if (t == null) { 231 t = exc; 232 } 233 throw new BuildException(exc.getMessage(), t); 234 } catch (FileNotFoundException exc) { 235 throw new BuildException(exc); 236 } catch (UnsupportedEncodingException exc) { 237 throw new BuildException("Encoding of project file " 238 + buildFileName + " is invalid.", 239 exc); 240 } catch (IOException exc) { 241 throw new BuildException("Error reading project file " 242 + buildFileName + ": " + exc.getMessage(), 243 exc); 244 } finally { 245 FileUtils.close(inputStream); 246 } 247 } 248 249 253 protected static AntHandler getMainHandler() { 254 return mainHandler; 255 } 256 257 261 protected static void setMainHandler(AntHandler handler) { 262 mainHandler = handler; 263 } 264 265 269 protected static AntHandler getProjectHandler() { 270 return projectHandler; 271 } 272 273 277 protected static void setProjectHandler(AntHandler handler) { 278 projectHandler = handler; 279 } 280 281 285 protected static AntHandler getTargetHandler() { 286 return targetHandler; 287 } 288 289 293 protected static void setTargetHandler(AntHandler handler) { 294 targetHandler = handler; 295 } 296 297 301 protected static AntHandler getElementHandler() { 302 return elementHandler; 303 } 304 305 309 protected static void setElementHandler(AntHandler handler) { 310 elementHandler = handler; 311 } 312 313 314 315 323 public static class AntHandler { 324 339 public void onStartElement(String uri, String tag, String qname, 340 Attributes attrs, 341 AntXMLContext context) 342 throws SAXParseException { 343 } 344 345 362 public AntHandler onStartChild(String uri, String tag, String qname, 363 Attributes attrs, 364 AntXMLContext context) 365 throws SAXParseException { 366 throw new SAXParseException ("Unexpected element \"" + qname 367 + " \"", context.getLocator()); 368 } 369 370 379 public void onEndChild(String uri, String tag, String qname, 380 AntXMLContext context) 381 throws SAXParseException { 382 } 383 384 391 public void onEndElement(String uri, String tag, 392 AntXMLContext context) { 393 } 394 395 408 public void characters(char[] buf, int start, int count, AntXMLContext context) 409 throws SAXParseException { 410 String s = new String (buf, start, count).trim(); 411 412 if (s.length() > 0) { 413 throw new SAXParseException ("Unexpected text \"" + s 414 + "\"", context.getLocator()); 415 } 416 } 417 418 424 protected void checkNamespace(String uri) { 425 426 } 427 } 428 429 434 public static class RootHandler extends DefaultHandler { 435 private Stack antHandlers = new Stack (); 436 private AntHandler currentHandler = null; 437 private AntXMLContext context; 438 439 445 public RootHandler(AntXMLContext context, AntHandler rootHandler) { 446 currentHandler = rootHandler; 447 antHandlers.push(currentHandler); 448 this.context = context; 449 } 450 451 455 public AntHandler getCurrentAntHandler() { 456 return currentHandler; 457 } 458 459 469 public InputSource resolveEntity(String publicId, 470 String systemId) { 471 472 context.getProject().log("resolving systemId: " 473 + systemId, Project.MSG_VERBOSE); 474 475 if (systemId.startsWith("file:")) { 476 String path = FILE_UTILS.fromURI(systemId); 477 478 File file = new File (path); 479 if (!file.isAbsolute()) { 480 file = FILE_UTILS.resolveFile(context.getBuildFileParent(), path); 481 context.getProject().log( 482 "Warning: '" + systemId + "' in " + context.getBuildFile() 483 + " should be expressed simply as '" + path.replace('\\', '/') 484 + "' for compliance with other XML tools", 485 Project.MSG_WARN); 486 } 487 context.getProject().log("file=" + file, Project.MSG_DEBUG); 488 try { 489 InputSource inputSource = 490 new InputSource (new FileInputStream (file)); 491 inputSource.setSystemId(FILE_UTILS.toURI(file.getAbsolutePath())); 492 return inputSource; 493 } catch (FileNotFoundException fne) { 494 context.getProject().log(file.getAbsolutePath() 495 + " could not be found", Project.MSG_WARN); 496 } 497 498 } 499 context.getProject().log( 501 "could not resolve systemId", Project.MSG_DEBUG); 502 return null; 503 } 504 505 519 public void startElement(String uri, String tag, String qname, Attributes attrs) 520 throws SAXParseException { 521 AntHandler next 522 = currentHandler.onStartChild(uri, tag, qname, attrs, context); 523 antHandlers.push(currentHandler); 524 currentHandler = next; 525 currentHandler.onStartElement(uri, tag, qname, attrs, context); 526 } 527 528 534 public void setDocumentLocator(Locator locator) { 535 context.setLocator(locator); 536 } 537 538 552 public void endElement(String uri, String name, String qName) throws SAXException { 553 currentHandler.onEndElement(uri, name, context); 554 AntHandler prev = (AntHandler) antHandlers.pop(); 555 currentHandler = prev; 556 if (currentHandler != null) { 557 currentHandler.onEndChild(uri, name, qName, context); 558 } 559 } 560 561 569 public void characters(char[] buf, int start, int count) 570 throws SAXParseException { 571 currentHandler.characters(buf, start, count, context); 572 } 573 574 580 public void startPrefixMapping(String prefix, String uri) { 581 context.startPrefixMapping(prefix, uri); 582 } 583 584 589 public void endPrefixMapping(String prefix) { 590 context.endPrefixMapping(prefix); 591 } 592 } 593 594 599 public static class MainHandler extends AntHandler { 600 601 612 public AntHandler onStartChild(String uri, String name, String qname, 613 Attributes attrs, 614 AntXMLContext context) 615 throws SAXParseException { 616 if (name.equals("project") 617 && (uri.equals("") || uri.equals(ANT_CORE_URI))) { 618 return ProjectHelper2.projectHandler; 619 } else { 620 if (name.equals(qname)) { 626 throw new SAXParseException ("Unexpected element \"{" + uri 627 + "}" + name + "\" {" + ANT_CORE_URI + "}" + name, 628 context.getLocator()); 629 } else { 630 throw new SAXParseException ("Unexpected element \"" + qname 631 + "\" " + name, context.getLocator()); 632 } 633 } 634 } 635 } 636 637 640 public static class ProjectHandler extends AntHandler { 641 642 661 public void onStartElement(String uri, String tag, String qname, 662 Attributes attrs, 663 AntXMLContext context) 664 throws SAXParseException { 665 String baseDir = null; 666 boolean nameAttributeSet = false; 667 668 Project project = context.getProject(); 669 context.getImplicitTarget().setLocation( 671 new Location(context.getLocator())); 672 673 683 684 for (int i = 0; i < attrs.getLength(); i++) { 685 String attrUri = attrs.getURI(i); 686 if (attrUri != null 687 && !attrUri.equals("") 688 && !attrUri.equals(uri)) { 689 continue; } 691 String key = attrs.getLocalName(i); 692 String value = attrs.getValue(i); 693 694 if (key.equals("default")) { 695 if (value != null && !value.equals("")) { 696 if (!context.isIgnoringProjectTag()) { 697 project.setDefault(value); 698 } 699 } 700 } else if (key.equals("name")) { 701 if (value != null) { 702 context.setCurrentProjectName(value); 703 nameAttributeSet = true; 704 if (!context.isIgnoringProjectTag()) { 705 project.setName(value); 706 project.addReference(value, project); 707 } 708 } 709 } else if (key.equals("id")) { 710 if (value != null) { 711 if (!context.isIgnoringProjectTag()) { 713 project.addReference(value, project); 714 } 715 } 716 } else if (key.equals("basedir")) { 717 if (!context.isIgnoringProjectTag()) { 718 baseDir = value; 719 } 720 } else { 721 throw new SAXParseException ("Unexpected attribute \"" 723 + attrs.getQName(i) + "\"", context.getLocator()); 724 } 725 } 726 727 String antFileProp = "ant.file." + context.getCurrentProjectName(); 729 String dup = project.getProperty(antFileProp); 730 if (dup != null && nameAttributeSet) { 731 File dupFile = new File (dup); 732 if (context.isIgnoringProjectTag() 733 && !dupFile.equals(context.getBuildFile())) { 734 project.log("Duplicated project name in import. Project " 735 + context.getCurrentProjectName() + " defined first in " 736 + dup + " and again in " + context.getBuildFile(), 737 Project.MSG_WARN); 738 } 739 } 740 741 if (context.getBuildFile() != null && nameAttributeSet) { 742 project.setUserProperty("ant.file." 743 + context.getCurrentProjectName(), 744 context.getBuildFile().toString()); 745 } 746 747 if (context.isIgnoringProjectTag()) { 748 return; 750 } 751 if (project.getProperty("basedir") != null) { 753 project.setBasedir(project.getProperty("basedir")); 754 } else { 755 if (baseDir == null) { 757 project.setBasedir(context.getBuildFileParent().getAbsolutePath()); 758 } else { 759 if ((new File (baseDir)).isAbsolute()) { 761 project.setBasedir(baseDir); 762 } else { 763 project.setBaseDir(FILE_UTILS.resolveFile( 764 context.getBuildFileParent(), baseDir)); 765 } 766 } 767 } 768 769 project.addTarget("", context.getImplicitTarget()); 770 context.setCurrentTarget(context.getImplicitTarget()); 771 } 772 773 792 public AntHandler onStartChild(String uri, String name, String qname, 793 Attributes attrs, 794 AntXMLContext context) 795 throws SAXParseException { 796 if (name.equals("target") 797 && (uri.equals("") || uri.equals(ANT_CORE_URI))) { 798 return ProjectHelper2.targetHandler; 799 } else { 800 return ProjectHelper2.elementHandler; 801 } 802 } 803 804 } 805 806 809 public static class TargetHandler extends AntHandler { 810 811 831 public void onStartElement(String uri, String tag, String qname, 832 Attributes attrs, 833 AntXMLContext context) 834 throws SAXParseException { 835 String name = null; 836 String depends = ""; 837 838 Project project = context.getProject(); 839 Target target = new Target(); 840 target.setProject(project); 841 target.setLocation(new Location(context.getLocator())); 842 context.addTarget(target); 843 844 for (int i = 0; i < attrs.getLength(); i++) { 845 String attrUri = attrs.getURI(i); 846 if (attrUri != null 847 && !attrUri.equals("") 848 && !attrUri.equals(uri)) { 849 continue; } 851 String key = attrs.getLocalName(i); 852 String value = attrs.getValue(i); 853 854 if (key.equals("name")) { 855 name = value; 856 if ("".equals(name)) { 857 throw new BuildException("name attribute must " 858 + "not be empty"); 859 } 860 } else if (key.equals("depends")) { 861 depends = value; 862 } else if (key.equals("if")) { 863 target.setIf(value); 864 } else if (key.equals("unless")) { 865 target.setUnless(value); 866 } else if (key.equals("id")) { 867 if (value != null && !value.equals("")) { 868 context.getProject().addReference(value, target); 869 } 870 } else if (key.equals("description")) { 871 target.setDescription(value); 872 } else { 873 throw new SAXParseException ("Unexpected attribute \"" 874 + key + "\"", context.getLocator()); 875 } 876 } 877 878 if (name == null) { 879 throw new SAXParseException ("target element appears without " 880 + "a name attribute", context.getLocator()); 881 } 882 883 if (context.getCurrentTargets().get(name) != null) { 885 throw new BuildException( 886 "Duplicate target '" + name + "'", target.getLocation()); 887 } 888 889 Hashtable projectTargets = project.getTargets(); 890 boolean usedTarget = false; 891 if (projectTargets.containsKey(name)) { 893 project.log("Already defined in main or a previous import, " 894 + "ignore " + name, Project.MSG_VERBOSE); 895 } else { 896 target.setName(name); 897 context.getCurrentTargets().put(name, target); 898 project.addOrReplaceTarget(name, target); 899 usedTarget = true; 900 } 901 902 if (depends.length() > 0) { 903 target.setDepends(depends); 904 } 905 906 if (context.isIgnoringProjectTag() && context.getCurrentProjectName() != null 907 && context.getCurrentProjectName().length() != 0) { 908 String newName = context.getCurrentProjectName() 911 + "." + name; 912 Target newTarget = usedTarget ? new Target(target) : target; 913 newTarget.setName(newName); 914 context.getCurrentTargets().put(newName, newTarget); 915 project.addOrReplaceTarget(newName, newTarget); 916 } 917 } 918 919 934 public AntHandler onStartChild(String uri, String name, String qname, 935 Attributes attrs, 936 AntXMLContext context) 937 throws SAXParseException { 938 return ProjectHelper2.elementHandler; 939 } 940 941 949 public void onEndElement(String uri, String tag, AntXMLContext context) { 950 context.setCurrentTarget(context.getImplicitTarget()); 951 } 952 } 953 954 957 public static class ElementHandler extends AntHandler { 958 959 962 public ElementHandler() { 963 } 964 965 983 public void onStartElement(String uri, String tag, String qname, 984 Attributes attrs, 985 AntXMLContext context) 986 throws SAXParseException { 987 RuntimeConfigurable parentWrapper = context.currentWrapper(); 988 Object parent = null; 989 990 if (parentWrapper != null) { 991 parent = parentWrapper.getProxy(); 992 } 993 994 996 UnknownElement task = new UnknownElement(tag); 997 task.setProject(context.getProject()); 998 task.setNamespace(uri); 999 task.setQName(qname); 1000 task.setTaskType( 1001 ProjectHelper.genComponentName(task.getNamespace(), tag)); 1002 task.setTaskName(qname); 1003 1004 Location location = new Location(context.getLocator().getSystemId(), 1005 context.getLocator().getLineNumber(), 1006 context.getLocator().getColumnNumber()); 1007 task.setLocation(location); 1008 task.setOwningTarget(context.getCurrentTarget()); 1009 1010 if (parent != null) { 1011 ((UnknownElement) parent).addChild(task); 1013 } else { 1014 context.getCurrentTarget().addTask(task); 1016 } 1017 1018 context.configureId(task, attrs); 1019 1020 1023 RuntimeConfigurable wrapper 1024 = new RuntimeConfigurable(task, task.getTaskName()); 1025 1026 for (int i = 0; i < attrs.getLength(); i++) { 1027 String name = attrs.getLocalName(i); 1028 String attrUri = attrs.getURI(i); 1029 if (attrUri != null 1030 && !attrUri.equals("") 1031 && !attrUri.equals(uri)) { 1032 name = attrUri + ":" + attrs.getQName(i); 1033 } 1034 String value = attrs.getValue(i); 1035 if (ANT_TYPE.equals(name) 1040 || (ANT_CORE_URI.equals(attrUri) 1041 && ANT_TYPE.equals(attrs.getLocalName(i)))) { 1042 name = ANT_TYPE; 1043 int index = value.indexOf(":"); 1044 if (index != -1) { 1045 String prefix = value.substring(0, index); 1046 String mappedUri = context.getPrefixMapping(prefix); 1047 if (mappedUri == null) { 1048 throw new BuildException( 1049 "Unable to find XML NS prefix " + prefix); 1050 } 1051 value = ProjectHelper.genComponentName( 1052 mappedUri, value.substring(index + 1)); 1053 } 1054 } 1055 wrapper.setAttribute(name, value); 1056 } 1057 1058 if (parentWrapper != null) { 1059 parentWrapper.addChild(wrapper); 1060 } 1061 1062 context.pushWrapper(wrapper); 1063 } 1064 1065 1078 public void characters(char[] buf, int start, int count, 1079 AntXMLContext context) 1080 throws SAXParseException { 1081 RuntimeConfigurable wrapper = context.currentWrapper(); 1082 wrapper.addText(buf, start, count); 1083 } 1084 1085 1102 public AntHandler onStartChild(String uri, String tag, String qname, 1103 Attributes attrs, 1104 AntXMLContext context) 1105 throws SAXParseException { 1106 return ProjectHelper2.elementHandler; 1107 } 1108 1109 1117 public void onEndElement(String uri, String tag, AntXMLContext context) { 1118 context.popWrapper(); 1119 } 1120 } 1121} 1122 | Popular Tags |