| 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 = <
|