1 18 19 package org.apache.tools.ant.helper; 20 21 import java.io.File ; 22 import java.io.FileInputStream ; 23 import java.io.FileNotFoundException ; 24 import java.io.IOException ; 25 import java.io.UnsupportedEncodingException ; 26 import java.util.Locale ; 27 import org.apache.tools.ant.BuildException; 28 import org.apache.tools.ant.IntrospectionHelper; 29 import org.apache.tools.ant.Location; 30 import org.apache.tools.ant.Project; 31 import org.apache.tools.ant.ProjectHelper; 32 import org.apache.tools.ant.RuntimeConfigurable; 33 import org.apache.tools.ant.Target; 34 import org.apache.tools.ant.Task; 35 import org.apache.tools.ant.TypeAdapter; 36 import org.apache.tools.ant.TaskContainer; 37 import org.apache.tools.ant.UnknownElement; 38 import org.apache.tools.ant.util.FileUtils; 39 import org.apache.tools.ant.util.JAXPUtils; 40 import org.xml.sax.AttributeList ; 41 import org.xml.sax.DocumentHandler ; 42 import org.xml.sax.HandlerBase ; 43 import org.xml.sax.InputSource ; 44 import org.xml.sax.Locator ; 45 import org.xml.sax.SAXException ; 46 import org.xml.sax.SAXParseException ; 47 import org.xml.sax.helpers.XMLReaderAdapter ; 48 49 53 public class ProjectHelperImpl extends ProjectHelper { 54 55 58 private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); 59 60 64 private org.xml.sax.Parser parser; 65 66 67 private Project project; 68 69 private File buildFile; 70 74 private File buildFileParent; 75 79 private Locator locator; 80 86 private Target implicitTarget = new Target(); 87 88 91 public ProjectHelperImpl() { 92 implicitTarget.setName(""); 93 } 94 95 103 public void parse(Project project, Object source) throws BuildException { 104 if (!(source instanceof File )) { 105 throw new BuildException("Only File source supported by " 106 + "default plugin"); 107 } 108 File bFile = (File ) source; 109 FileInputStream inputStream = null; 110 InputSource inputSource = null; 111 112 this.project = project; 113 this.buildFile = new File (bFile.getAbsolutePath()); 114 buildFileParent = new File (this.buildFile.getParent()); 115 116 try { 117 try { 118 parser = JAXPUtils.getParser(); 119 } catch (BuildException e) { 120 parser = new XMLReaderAdapter (JAXPUtils.getXMLReader()); 121 } 122 123 124 String uri = FILE_UTILS.toURI(bFile.getAbsolutePath()); 125 inputStream = new FileInputStream (bFile); 126 inputSource = new InputSource (inputStream); 127 inputSource.setSystemId(uri); 128 project.log("parsing buildfile " + bFile + " with URI = " 129 + uri, Project.MSG_VERBOSE); 130 HandlerBase hb = new RootHandler(this); 131 parser.setDocumentHandler(hb); 132 parser.setEntityResolver(hb); 133 parser.setErrorHandler(hb); 134 parser.setDTDHandler(hb); 135 parser.parse(inputSource); 136 } catch (SAXParseException exc) { 137 Location location = 138 new Location(exc.getSystemId(), exc.getLineNumber(), 139 exc.getColumnNumber()); 140 141 Throwable t = exc.getException(); 142 if (t instanceof BuildException) { 143 BuildException be = (BuildException) t; 144 if (be.getLocation() == Location.UNKNOWN_LOCATION) { 145 be.setLocation(location); 146 } 147 throw be; 148 } 149 150 throw new BuildException(exc.getMessage(), t, location); 151 } catch (SAXException exc) { 152 Throwable t = exc.getException(); 153 if (t instanceof BuildException) { 154 throw (BuildException) t; 155 } 156 throw new BuildException(exc.getMessage(), t); 157 } catch (FileNotFoundException exc) { 158 throw new BuildException(exc); 159 } catch (UnsupportedEncodingException exc) { 160 throw new BuildException("Encoding of project file is invalid.", 161 exc); 162 } catch (IOException exc) { 163 throw new BuildException("Error reading project file: " 164 + exc.getMessage(), exc); 165 } finally { 166 FileUtils.close(inputStream); 167 } 168 } 169 170 182 static class AbstractHandler extends HandlerBase { 183 185 190 protected DocumentHandler parentHandler; 191 192 197 ProjectHelperImpl helperImpl; 198 200 211 public AbstractHandler(ProjectHelperImpl helperImpl, DocumentHandler parentHandler) { 212 this.parentHandler = parentHandler; 213 this.helperImpl = helperImpl; 214 215 helperImpl.parser.setDocumentHandler(this); 217 } 218 219 231 public void startElement(String tag, AttributeList attrs) throws SAXParseException { 232 throw new SAXParseException ("Unexpected element \"" + tag + "\"", helperImpl.locator); 233 } 234 235 247 public void characters(char[] buf, int start, int count) throws SAXParseException { 248 String s = new String (buf, start, count).trim(); 249 250 if (s.length() > 0) { 251 throw new SAXParseException ("Unexpected text \"" + s + "\"", helperImpl.locator); 252 } 253 } 254 255 266 public void endElement(String name) throws SAXException { 267 helperImpl.parser.setDocumentHandler(parentHandler); 269 } 270 } 271 272 275 static class RootHandler extends HandlerBase { 276 ProjectHelperImpl helperImpl; 278 280 public RootHandler(ProjectHelperImpl helperImpl) { 281 this.helperImpl = helperImpl; 282 } 283 284 293 public InputSource resolveEntity(String publicId, 294 String systemId) { 295 296 helperImpl.project.log("resolving systemId: " + systemId, Project.MSG_VERBOSE); 297 298 if (systemId.startsWith("file:")) { 299 String path = FILE_UTILS.fromURI(systemId); 300 301 File file = new File (path); 302 if (!file.isAbsolute()) { 303 file = FILE_UTILS.resolveFile(helperImpl.buildFileParent, path); 304 helperImpl.project.log( 305 "Warning: '" + systemId + "' in " + helperImpl.buildFile 306 + " should be expressed simply as '" + path.replace('\\', '/') 307 + "' for compliance with other XML tools", 308 Project.MSG_WARN); 309 } 310 try { 311 InputSource inputSource = new InputSource (new FileInputStream (file)); 312 inputSource.setSystemId(FILE_UTILS.toURI(file.getAbsolutePath())); 313 return inputSource; 314 } catch (FileNotFoundException fne) { 315 helperImpl.project.log(file.getAbsolutePath() + " could not be found", 316 Project.MSG_WARN); 317 } 318 } 319 return null; 321 } 322 323 335 public void startElement(String tag, AttributeList attrs) throws SAXParseException { 336 if (tag.equals("project")) { 337 new ProjectHandler(helperImpl, this).init(tag, attrs); 338 } else { 339 throw new SAXParseException ("Config file is not of expected " 340 + "XML type", helperImpl.locator); 341 } 342 } 343 344 350 public void setDocumentLocator(Locator locator) { 351 helperImpl.locator = locator; 352 } 353 } 354 355 358 static class ProjectHandler extends AbstractHandler { 359 360 367 public ProjectHandler(ProjectHelperImpl helperImpl, DocumentHandler parentHandler) { 368 super(helperImpl, parentHandler); 369 } 370 371 387 public void init(String tag, AttributeList attrs) throws SAXParseException { 388 String def = null; 389 String name = null; 390 String id = null; 391 String baseDir = null; 392 393 for (int i = 0; i < attrs.getLength(); i++) { 394 String key = attrs.getName(i); 395 String value = attrs.getValue(i); 396 397 if (key.equals("default")) { 398 def = value; 399 } else if (key.equals("name")) { 400 name = value; 401 } else if (key.equals("id")) { 402 id = value; 403 } else if (key.equals("basedir")) { 404 baseDir = value; 405 } else { 406 throw new SAXParseException ("Unexpected attribute \"" + attrs.getName(i) + "\"", 407 helperImpl.locator); 408 } 409 } 410 411 if (def != null && !def.equals("")) { 412 helperImpl.project.setDefaultTarget(def); 413 } else { 414 throw new BuildException("The default attribute is required"); 415 } 416 417 if (name != null) { 418 helperImpl.project.setName(name); 419 helperImpl.project.addReference(name, helperImpl.project); 420 } 421 422 if (id != null) { 423 helperImpl.project.addReference(id, helperImpl.project); 424 } 425 426 if (helperImpl.project.getProperty("basedir") != null) { 427 helperImpl.project.setBasedir(helperImpl.project.getProperty("basedir")); 428 } else { 429 if (baseDir == null) { 430 helperImpl.project.setBasedir(helperImpl.buildFileParent.getAbsolutePath()); 431 } else { 432 if ((new File (baseDir)).isAbsolute()) { 434 helperImpl.project.setBasedir(baseDir); 435 } else { 436 File resolvedBaseDir = FILE_UTILS.resolveFile( 437 helperImpl.buildFileParent, baseDir); 438 helperImpl.project.setBaseDir(resolvedBaseDir); 439 } 440 } 441 } 442 443 helperImpl.project.addTarget("", helperImpl.implicitTarget); 444 } 445 446 461 public void startElement(String name, AttributeList attrs) throws SAXParseException { 462 if (name.equals("target")) { 463 handleTarget(name, attrs); 464 } else { 465 handleElement(helperImpl, this, helperImpl.implicitTarget, 466 name, attrs); 467 } 468 } 469 470 482 private void handleTarget(String tag, AttributeList attrs) throws SAXParseException { 483 new TargetHandler(helperImpl, this).init(tag, attrs); 484 } 485 486 } 487 488 491 static class TargetHandler extends AbstractHandler { 492 private Target target; 493 494 501 public TargetHandler(ProjectHelperImpl helperImpl, DocumentHandler parentHandler) { 502 super(helperImpl, parentHandler); 503 } 504 505 522 public void init(String tag, AttributeList attrs) throws SAXParseException { 523 String name = null; 524 String depends = ""; 525 String ifCond = null; 526 String unlessCond = null; 527 String id = null; 528 String description = null; 529 530 for (int i = 0; i < attrs.getLength(); i++) { 531 String key = attrs.getName(i); 532 String value = attrs.getValue(i); 533 534 if (key.equals("name")) { 535 name = value; 536 if (name.equals("")) { 537 throw new BuildException("name attribute must not" 538 + " be empty", 539 new Location(helperImpl.locator)); 540 } 541 } else if (key.equals("depends")) { 542 depends = value; 543 } else if (key.equals("if")) { 544 ifCond = value; 545 } else if (key.equals("unless")) { 546 unlessCond = value; 547 } else if (key.equals("id")) { 548 id = value; 549 } else if (key.equals("description")) { 550 description = value; 551 } else { 552 throw new SAXParseException ("Unexpected attribute \"" 553 + key + "\"", helperImpl.locator); 554 } 555 } 556 557 if (name == null) { 558 throw new SAXParseException ("target element appears without a name attribute", 559 helperImpl.locator); 560 } 561 562 target = new Target(); 563 564 target.addDependency(""); 566 567 target.setName(name); 568 target.setIf(ifCond); 569 target.setUnless(unlessCond); 570 target.setDescription(description); 571 helperImpl.project.addTarget(name, target); 572 573 if (id != null && !id.equals("")) { 574 helperImpl.project.addReference(id, target); 575 } 576 577 579 if (depends.length() > 0) { 580 target.setDepends(depends); 581 } 582 } 583 584 595 public void startElement(String name, AttributeList attrs) throws SAXParseException { 596 handleElement(helperImpl, this, target, name, attrs); 597 } 598 } 599 600 608 private static void handleElement(ProjectHelperImpl helperImpl, 609 DocumentHandler parent, 610 Target target, String elementName, 611 AttributeList attrs) 612 throws SAXParseException { 613 if (elementName.equals("description")) { 614 new DescriptionHandler(helperImpl, parent); 615 } else if (helperImpl.project.getDataTypeDefinitions() 616 .get(elementName) != null) { 617 new DataTypeHandler(helperImpl, parent, target) 618 .init(elementName, attrs); 619 } else { 620 new TaskHandler(helperImpl, parent, target, null, target) 621 .init(elementName, attrs); 622 } 623 } 624 625 628 static class DescriptionHandler extends AbstractHandler { 629 630 637 public DescriptionHandler(ProjectHelperImpl helperImpl, 638 DocumentHandler parentHandler) { 639 super(helperImpl, parentHandler); 640 } 641 642 650 public void characters(char[] buf, int start, int count) { 651 String text = new String (buf, start, count); 652 String currentDescription = helperImpl.project.getDescription(); 653 if (currentDescription == null) { 654 helperImpl.project.setDescription(text); 655 } else { 656 helperImpl.project.setDescription(currentDescription + text); 657 } 658 } 659 660 } 661 662 665 static class TaskHandler extends AbstractHandler { 666 667 private Target target; 668 672 private TaskContainer container; 673 676 private Task task; 677 681 private RuntimeConfigurable parentWrapper; 682 688 private RuntimeConfigurable wrapper = null; 689 690 706 public TaskHandler(ProjectHelperImpl helperImpl, DocumentHandler parentHandler, 707 TaskContainer container, 708 RuntimeConfigurable parentWrapper, Target target) { 709 super(helperImpl, parentHandler); 710 this.container = container; 711 this.parentWrapper = parentWrapper; 712 this.target = target; 713 } 714 715 731 public void init(String tag, AttributeList attrs) throws SAXParseException { 732 try { 733 task = helperImpl.project.createTask(tag); 734 } catch (BuildException e) { 735 } 738 739 if (task == null) { 740 task = new UnknownElement(tag); 741 task.setProject(helperImpl.project); 742 task.setTaskName(tag); 744 } 745 746 task.setLocation(new Location(helperImpl.locator)); 747 helperImpl.configureId(task, attrs); 748 749 task.setOwningTarget(target); 750 container.addTask(task); 751 task.init(); 752 wrapper = task.getRuntimeConfigurableWrapper(); 753 wrapper.setAttributes(attrs); 754 if (parentWrapper != null) { 755 parentWrapper.addChild(wrapper); 756 } 757 } 758 759 767 public void characters(char[] buf, int start, int count) { 768 wrapper.addText(buf, start, count); 769 } 770 771 784 public void startElement(String name, AttributeList attrs) throws SAXParseException { 785 if (task instanceof TaskContainer) { 786 new TaskHandler(helperImpl, this, (TaskContainer) task, 788 wrapper, target).init(name, attrs); 789 } else { 790 new NestedElementHandler(helperImpl, this, task, 791 wrapper, target).init(name, attrs); 792 } 793 } 794 } 795 796 799 static class NestedElementHandler extends AbstractHandler { 800 801 private Object parent; 802 803 private Object child; 804 808 private RuntimeConfigurable parentWrapper; 809 815 private RuntimeConfigurable childWrapper = null; 816 817 private Target target; 818 819 835 public NestedElementHandler(ProjectHelperImpl helperImpl, 836 DocumentHandler parentHandler, 837 Object parent, 838 RuntimeConfigurable parentWrapper, 839 Target target) { 840 super(helperImpl, parentHandler); 841 842 if (parent instanceof TypeAdapter) { 843 this.parent = ((TypeAdapter) parent).getProxy(); 844 } else { 845 this.parent = parent; 846 } 847 this.parentWrapper = parentWrapper; 848 this.target = target; 849 } 850 851 867 public void init(String propType, AttributeList attrs) throws SAXParseException { 868 Class parentClass = parent.getClass(); 869 IntrospectionHelper ih = 870 IntrospectionHelper.getHelper(helperImpl.project, parentClass); 871 872 try { 873 String elementName = propType.toLowerCase(Locale.US); 874 if (parent instanceof UnknownElement) { 875 UnknownElement uc = new UnknownElement(elementName); 876 uc.setProject(helperImpl.project); 877 ((UnknownElement) parent).addChild(uc); 878 child = uc; 879 } else { 880 child = ih.createElement(helperImpl.project, parent, elementName); 881 } 882 883 helperImpl.configureId(child, attrs); 884 885 childWrapper = new RuntimeConfigurable(child, propType); 886 childWrapper.setAttributes(attrs); 887 parentWrapper.addChild(childWrapper); 888 } catch (BuildException exc) { 889 throw new SAXParseException (exc.getMessage(), helperImpl.locator, exc); 890 } 891 } 892 893 901 public void characters(char[] buf, int start, int count) { 902 childWrapper.addText(buf, start, count); 903 } 904 905 918 public void startElement(String name, AttributeList attrs) throws SAXParseException { 919 if (child instanceof TaskContainer) { 920 new TaskHandler(helperImpl, this, (TaskContainer) child, 923 childWrapper, target).init(name, attrs); 924 } else { 925 new NestedElementHandler(helperImpl, this, child, 926 childWrapper, target).init(name, attrs); 927 } 928 } 929 } 930 931 934 static class DataTypeHandler extends AbstractHandler { 935 936 private Target target; 937 938 private Object element; 939 940 private RuntimeConfigurable wrapper = null; 941 942 952 public DataTypeHandler(ProjectHelperImpl helperImpl, 953 DocumentHandler parentHandler, Target target) { 954 super(helperImpl, parentHandler); 955 this.target = target; 956 } 957 958 974 public void init(String propType, AttributeList attrs) throws SAXParseException { 975 try { 976 element = helperImpl.project.createDataType(propType); 977 if (element == null) { 978 throw new BuildException("Unknown data type " + propType); 979 } 980 981 wrapper = new RuntimeConfigurable(element, propType); 982 wrapper.setAttributes(attrs); 983 target.addDataType(wrapper); 984 } catch (BuildException exc) { 985 throw new SAXParseException (exc.getMessage(), helperImpl.locator, exc); 986 } 987 } 988 989 999 public void characters(char[] buf, int start, int count) { 1000 wrapper.addText(buf, start, count); 1001 } 1002 1003 1015 public void startElement(String name, AttributeList attrs) throws SAXParseException { 1016 new NestedElementHandler(helperImpl, this, element, wrapper, target).init(name, attrs); 1017 } 1018 } 1019 1020 1030 private void configureId(Object target, AttributeList attr) { 1031 String id = attr.getValue("id"); 1032 if (id != null) { 1033 project.addReference(id, target); 1034 } 1035 } 1036} 1037 | Popular Tags |