1 11 package org.eclipse.core.internal.resources; 12 13 import java.io.*; 14 import java.net.URI ; 15 import java.net.URISyntaxException ; 16 import java.util.*; 17 import javax.xml.parsers.*; 18 import org.eclipse.core.filesystem.URIUtil; 19 import org.eclipse.core.internal.events.BuildCommand; 20 import org.eclipse.core.internal.localstore.SafeFileInputStream; 21 import org.eclipse.core.internal.utils.Messages; 22 import org.eclipse.core.internal.utils.Policy; 23 import org.eclipse.core.resources.*; 24 import org.eclipse.core.runtime.*; 25 import org.eclipse.osgi.util.NLS; 26 import org.xml.sax.*; 27 import org.xml.sax.helpers.DefaultHandler ; 28 29 public class ProjectDescriptionReader extends DefaultHandler implements IModelObjectConstants { 30 31 protected static final int S_BUILD_COMMAND = 0; 33 protected static final int S_BUILD_COMMAND_ARGUMENTS = 1; 34 protected static final int S_BUILD_COMMAND_NAME = 2; 35 protected static final int S_BUILD_COMMAND_TRIGGERS = 3; 36 protected static final int S_BUILD_SPEC = 4; 37 protected static final int S_DICTIONARY = 5; 38 protected static final int S_DICTIONARY_KEY = 6; 39 protected static final int S_DICTIONARY_VALUE = 7; 40 protected static final int S_INITIAL = 8; 41 protected static final int S_LINK = 9; 42 protected static final int S_LINK_LOCATION = 10; 43 protected static final int S_LINK_LOCATION_URI = 11; 44 protected static final int S_LINK_PATH = 12; 45 protected static final int S_LINK_TYPE = 13; 46 protected static final int S_LINKED_RESOURCES = 14; 47 protected static final int S_NATURE_NAME = 15; 48 protected static final int S_NATURES = 16; 49 protected static final int S_PROJECT_COMMENT = 17; 50 protected static final int S_PROJECT_DESC = 18; 51 protected static final int S_PROJECT_NAME = 19; 52 protected static final int S_PROJECTS = 20; 53 protected static final int S_REFERENCED_PROJECT_NAME = 21; 54 55 58 private static SAXParser singletonParser; 59 60 protected final StringBuffer charBuffer = new StringBuffer (); 61 62 protected Stack objectStack; 63 protected MultiStatus problems; 64 65 68 private final IProject project; 69 ProjectDescription projectDescription = null; 71 72 protected int state = S_INITIAL; 73 74 public ProjectDescriptionReader() { 75 this.project = null; 76 } 77 78 public ProjectDescriptionReader(IProject project) { 79 this.project = project; 80 } 81 82 85 public void characters(char[] chars, int offset, int length) { 86 charBuffer.append(chars, offset, length); 88 } 89 90 93 private void endBuildCommandElement(String elementName) { 94 if (elementName.equals(BUILD_COMMAND)) { 95 BuildCommand command = (BuildCommand) objectStack.pop(); 97 ArrayList commandList = (ArrayList) objectStack.peek(); 99 commandList.add(command); 100 state = S_BUILD_SPEC; 101 } 102 } 103 104 107 private void endBuildSpecElement(String elementName) { 108 if (elementName.equals(BUILD_SPEC)) { 109 ArrayList commands = (ArrayList) objectStack.pop(); 112 state = S_PROJECT_DESC; 113 if (commands.isEmpty()) 114 return; 115 ICommand[] commandArray = ((ICommand[]) commands.toArray(new ICommand[commands.size()])); 116 projectDescription.setBuildSpec(commandArray); 117 } 118 } 119 120 124 private void endBuildTriggersElement(String elementName) { 125 if (elementName.equals(BUILD_TRIGGERS)) { 126 state = S_BUILD_COMMAND; 127 BuildCommand command = (BuildCommand) objectStack.peek(); 128 command.setConfigurable(true); 130 command.setBuilding(IncrementalProjectBuilder.AUTO_BUILD, false); 132 command.setBuilding(IncrementalProjectBuilder.CLEAN_BUILD, false); 133 command.setBuilding(IncrementalProjectBuilder.FULL_BUILD, false); 134 command.setBuilding(IncrementalProjectBuilder.INCREMENTAL_BUILD, false); 135 136 StringTokenizer tokens = new StringTokenizer(charBuffer.toString(), ","); while (tokens.hasMoreTokens()) { 139 String next = tokens.nextToken(); 140 if (next.toLowerCase().equals(TRIGGER_AUTO)) { 141 command.setBuilding(IncrementalProjectBuilder.AUTO_BUILD, true); 142 } else if (next.toLowerCase().equals(TRIGGER_CLEAN)) { 143 command.setBuilding(IncrementalProjectBuilder.CLEAN_BUILD, true); 144 } else if (next.toLowerCase().equals(TRIGGER_FULL)) { 145 command.setBuilding(IncrementalProjectBuilder.FULL_BUILD, true); 146 } else if (next.toLowerCase().equals(TRIGGER_INCREMENTAL)) { 147 command.setBuilding(IncrementalProjectBuilder.INCREMENTAL_BUILD, true); 148 } 149 } 150 } 151 } 152 153 156 private void endDictionary(String elementName) { 157 if (elementName.equals(DICTIONARY)) { 158 String value = (String ) objectStack.pop(); 163 String key = (String ) objectStack.pop(); 164 ((HashMap) objectStack.peek()).put(key, value); 165 state = S_BUILD_COMMAND_ARGUMENTS; 166 } 167 } 168 169 private void endDictionaryKey(String elementName) { 170 if (elementName.equals(KEY)) { 171 String value = (String ) objectStack.pop(); 174 String oldKey = (String ) objectStack.pop(); 175 String newKey = charBuffer.toString(); 176 if (oldKey != null && oldKey.length() != 0) { 177 parseProblem(NLS.bind(Messages.projRead_whichKey, oldKey, newKey)); 178 objectStack.push(oldKey); 179 } else { 180 objectStack.push(newKey); 181 } 182 objectStack.push(value); 184 state = S_DICTIONARY; 185 } 186 } 187 188 private void endDictionaryValue(String elementName) { 189 if (elementName.equals(VALUE)) { 190 String newValue = charBuffer.toString(); 191 String oldValue = (String ) objectStack.pop(); 193 if (oldValue != null && oldValue.length() != 0) { 194 parseProblem(NLS.bind(Messages.projRead_whichValue, oldValue, newValue)); 195 objectStack.push(oldValue); 196 } else { 197 objectStack.push(newValue); 198 } 199 state = S_DICTIONARY; 200 } 201 } 202 203 206 public void endElement(String uri, String elementName, String qname) { 207 switch (state) { 208 case S_PROJECT_DESC : 209 break; 211 case S_PROJECT_NAME : 212 if (elementName.equals(NAME)) { 213 projectDescription.setName(charBuffer.toString().trim()); 216 state = S_PROJECT_DESC; 217 } 218 break; 219 case S_PROJECTS : 220 if (elementName.equals(PROJECTS)) { 221 endProjectsElement(elementName); 222 state = S_PROJECT_DESC; 223 } 224 break; 225 case S_DICTIONARY : 226 endDictionary(elementName); 227 break; 228 case S_BUILD_COMMAND_ARGUMENTS : 229 if (elementName.equals(ARGUMENTS)) { 230 HashMap dictionaryArgs = (HashMap) objectStack.pop(); 233 state = S_BUILD_COMMAND; 234 if (dictionaryArgs.isEmpty()) 235 break; 236 ((BuildCommand) objectStack.peek()).setArguments(dictionaryArgs); 238 } 239 break; 240 case S_BUILD_COMMAND : 241 endBuildCommandElement(elementName); 242 break; 243 case S_BUILD_SPEC : 244 endBuildSpecElement(elementName); 245 break; 246 case S_BUILD_COMMAND_TRIGGERS : 247 endBuildTriggersElement(elementName); 248 break; 249 case S_NATURES : 250 endNaturesElement(elementName); 251 break; 252 case S_LINK : 253 endLinkElement(elementName); 254 break; 255 case S_LINKED_RESOURCES : 256 endLinkedResourcesElement(elementName); 257 return; 258 case S_PROJECT_COMMENT : 259 if (elementName.equals(COMMENT)) { 260 projectDescription.setComment(charBuffer.toString()); 261 state = S_PROJECT_DESC; 262 } 263 break; 264 case S_REFERENCED_PROJECT_NAME : 265 if (elementName.equals(PROJECT)) { 266 ((ArrayList) objectStack.peek()).add(charBuffer.toString().trim()); 271 state = S_PROJECTS; 272 } 273 break; 274 case S_BUILD_COMMAND_NAME : 275 if (elementName.equals(NAME)) { 276 ((BuildCommand) objectStack.peek()).setName(charBuffer.toString().trim()); 280 state = S_BUILD_COMMAND; 281 } 282 break; 283 case S_DICTIONARY_KEY : 284 endDictionaryKey(elementName); 285 break; 286 case S_DICTIONARY_VALUE : 287 endDictionaryValue(elementName); 288 break; 289 case S_NATURE_NAME : 290 if (elementName.equals(NATURE)) { 291 ((ArrayList) objectStack.peek()).add(charBuffer.toString().trim()); 295 state = S_NATURES; 296 } 297 break; 298 case S_LINK_PATH : 299 endLinkPath(elementName); 300 break; 301 case S_LINK_TYPE : 302 endLinkType(elementName); 303 break; 304 case S_LINK_LOCATION : 305 endLinkLocation(elementName); 306 break; 307 case S_LINK_LOCATION_URI : 308 endLinkLocationURI(elementName); 309 break; 310 } 311 charBuffer.setLength(0); 312 } 313 314 317 private void endLinkedResourcesElement(String elementName) { 318 if (elementName.equals(LINKED_RESOURCES)) { 319 HashMap linkedResources = (HashMap) objectStack.pop(); 320 state = S_PROJECT_DESC; 321 if (linkedResources.isEmpty()) 322 return; 323 projectDescription.setLinkDescriptions(linkedResources); 324 } 325 } 326 327 330 private void endLinkElement(String elementName) { 331 if (elementName.equals(LINK)) { 332 state = S_LINKED_RESOURCES; 333 LinkDescription link = (LinkDescription) objectStack.pop(); 335 IPath path = link.getProjectRelativePath(); 337 int type = link.getType(); 338 URI location = link.getLocationURI(); 339 if (location == null) { 340 parseProblem(NLS.bind(Messages.projRead_badLinkLocation, path, Integer.toString(type))); 341 return; 342 } 343 if ((path == null) || path.segmentCount() == 0) { 344 parseProblem(NLS.bind(Messages.projRead_emptyLinkName, Integer.toString(type), location)); 345 return; 346 } 347 if (type == -1) { 348 parseProblem(NLS.bind(Messages.projRead_badLinkType, path, location)); 349 return; 350 } 351 352 ((HashMap) objectStack.peek()).put(link.getProjectRelativePath(), link); 354 } 355 } 356 357 362 private void endLinkLocation(String elementName) { 363 if (elementName.equals(LOCATION)) { 364 String newLocation = charBuffer.toString().trim(); 366 URI oldLocation = ((LinkDescription) objectStack.peek()).getLocationURI(); 368 if (oldLocation != null) { 369 parseProblem(NLS.bind(Messages.projRead_badLocation, oldLocation, newLocation)); 370 } else { 371 ((LinkDescription) objectStack.peek()).setLocationURI(URIUtil.toURI(Path.fromPortableString(newLocation))); 372 } 373 state = S_LINK; 374 } 375 } 376 377 382 private void endLinkLocationURI(String elementName) { 383 if (elementName.equals(LOCATION_URI)) { 384 String newLocation = charBuffer.toString().trim(); 386 URI oldLocation = ((LinkDescription) objectStack.peek()).getLocationURI(); 388 if (oldLocation != null) { 389 parseProblem(NLS.bind(Messages.projRead_badLocation, oldLocation, newLocation)); 390 } else { 391 try { 392 ((LinkDescription) objectStack.peek()).setLocationURI(new URI (newLocation)); 393 } catch (URISyntaxException e) { 394 String msg = Messages.projRead_failureReadingProjectDesc; 395 problems.add(new Status(IStatus.WARNING, ResourcesPlugin.PI_RESOURCES, IResourceStatus.FAILED_READ_METADATA, msg, e)); 396 } 397 } 398 state = S_LINK; 399 } 400 } 401 402 private void endLinkPath(String elementName) { 403 if (elementName.equals(NAME)) { 404 IPath newPath = new Path(charBuffer.toString()); 405 IPath oldPath = ((LinkDescription) objectStack.peek()).getProjectRelativePath(); 408 if (oldPath.segmentCount() != 0) { 409 parseProblem(NLS.bind(Messages.projRead_badLinkName, oldPath, newPath)); 410 } else { 411 ((LinkDescription) objectStack.peek()).setPath(newPath); 412 } 413 state = S_LINK; 414 } 415 } 416 417 private void endLinkType(String elementName) { 418 if (elementName.equals(TYPE)) { 419 int newType = IResource.FILE; 422 try { 423 newType = Integer.parseInt(charBuffer.toString().trim()); 427 } catch (NumberFormatException e) { 428 log(e); 429 } 430 int oldType = ((LinkDescription) objectStack.peek()).getType(); 433 if (oldType != -1) { 434 parseProblem(NLS.bind(Messages.projRead_badLinkType2, Integer.toString(oldType), Integer.toString(newType))); 435 } else { 436 ((LinkDescription) objectStack.peek()).setType(newType); 437 } 438 state = S_LINK; 439 } 440 } 441 442 445 private void endNaturesElement(String elementName) { 446 if (elementName.equals(NATURES)) { 447 ArrayList natures = (ArrayList) objectStack.pop(); 449 state = S_PROJECT_DESC; 450 if (natures.size() == 0) 451 return; 452 String [] natureNames = (String []) natures.toArray(new String [natures.size()]); 453 projectDescription.setNatureIds(natureNames); 454 } 455 } 456 457 460 private void endProjectsElement(String elementName) { 461 ArrayList referencedProjects = (ArrayList) objectStack.pop(); 463 if (referencedProjects.size() == 0) 464 return; 467 IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); 468 IProject[] projects = new IProject[referencedProjects.size()]; 469 for (int i = 0; i < projects.length; i++) { 470 projects[i] = root.getProject((String ) referencedProjects.get(i)); 471 } 472 projectDescription.setReferencedProjects(projects); 473 } 474 475 478 public void error(SAXParseException error) { 479 log(error); 480 } 481 482 485 public void fatalError(SAXParseException error) throws SAXException { 486 String message = error.getMessage(); 488 if (project != null) 489 message = NLS.bind(Messages.resources_readMeta, project.getName()); 490 problems.add(new Status(IStatus.ERROR, ResourcesPlugin.PI_RESOURCES, IResourceStatus.FAILED_READ_METADATA, message == null ? "" : message, error)); throw error; 492 } 493 494 protected void log(Exception ex) { 495 String message = ex.getMessage(); 496 if (project != null) 497 message = NLS.bind(Messages.resources_readMeta, project.getName()); 498 problems.add(new Status(IStatus.WARNING, ResourcesPlugin.PI_RESOURCES, IResourceStatus.FAILED_READ_METADATA, message == null ? "" : message, ex)); } 500 501 private void parseProblem(String errorMessage) { 502 problems.add(new Status(IStatus.WARNING, ResourcesPlugin.PI_RESOURCES, IResourceStatus.FAILED_READ_METADATA, errorMessage, null)); 503 } 504 505 private void parseProjectDescription(String elementName) { 506 if (elementName.equals(NAME)) { 507 state = S_PROJECT_NAME; 508 return; 509 } 510 if (elementName.equals(COMMENT)) { 511 state = S_PROJECT_COMMENT; 512 return; 513 } 514 if (elementName.equals(PROJECTS)) { 515 state = S_PROJECTS; 516 objectStack.push(new ArrayList()); 522 return; 523 } 524 if (elementName.equals(BUILD_SPEC)) { 525 state = S_BUILD_SPEC; 526 objectStack.push(new ArrayList()); 531 return; 532 } 533 if (elementName.equals(NATURES)) { 534 state = S_NATURES; 535 objectStack.push(new ArrayList()); 537 return; 538 } 539 if (elementName.equals(LINKED_RESOURCES)) { 540 objectStack.push(new HashMap()); 542 state = S_LINKED_RESOURCES; 543 return; 544 } 545 } 546 547 public ProjectDescription read(InputSource input) { 548 problems = new MultiStatus(ResourcesPlugin.PI_RESOURCES, IResourceStatus.FAILED_READ_METADATA, Messages.projRead_failureReadingProjectDesc, null); 549 objectStack = new Stack(); 550 state = S_INITIAL; 551 try { 552 createParser().parse(input, this); 553 } catch (ParserConfigurationException e) { 554 log(e); 555 } catch (IOException e) { 556 log(e); 557 } catch (SAXException e) { 558 log(e); 559 } 560 switch (problems.getSeverity()) { 561 case IStatus.ERROR : 562 Policy.log(problems); 563 return null; 564 case IStatus.WARNING : 565 case IStatus.INFO : 566 Policy.log(problems); 567 case IStatus.OK : 568 default : 569 return projectDescription; 570 } 571 } 572 573 576 private static synchronized SAXParser createParser() throws ParserConfigurationException, SAXException { 577 if (singletonParser == null) { 578 SAXParserFactory factory = SAXParserFactory.newInstance(); 579 factory.setNamespaceAware(true); 580 try { 581 factory.setFeature("http://xml.org/sax/features/string-interning", true); } catch (SAXException e) { 583 } 585 singletonParser = factory.newSAXParser(); 586 } 587 return singletonParser; 588 } 589 590 593 public ProjectDescription read(IPath location) throws IOException { 594 BufferedInputStream file = null; 595 try { 596 file = new BufferedInputStream(new FileInputStream(location.toFile())); 597 return read(new InputSource(file)); 598 } finally { 599 if (file != null) 600 file.close(); 601 } 602 } 603 604 608 public ProjectDescription read(IPath location, IPath tempLocation) throws IOException { 609 SafeFileInputStream file = new SafeFileInputStream(location.toOSString(), tempLocation.toOSString()); 610 try { 611 return read(new InputSource(file)); 612 } finally { 613 file.close(); 614 } 615 } 616 617 620 public void startElement(String uri, String elementName, String qname, Attributes attributes) throws SAXException { 621 charBuffer.setLength(0); 623 switch (state) { 624 case S_INITIAL : 625 if (elementName.equals(PROJECT_DESCRIPTION)) { 626 state = S_PROJECT_DESC; 627 projectDescription = new ProjectDescription(); 628 } else { 629 throw (new SAXException(NLS.bind(Messages.projRead_notProjectDescription, elementName))); 630 } 631 break; 632 case S_PROJECT_DESC : 633 parseProjectDescription(elementName); 634 break; 635 case S_PROJECTS : 636 if (elementName.equals(PROJECT)) { 637 state = S_REFERENCED_PROJECT_NAME; 638 } 639 break; 640 case S_BUILD_SPEC : 641 if (elementName.equals(BUILD_COMMAND)) { 642 state = S_BUILD_COMMAND; 643 objectStack.push(new BuildCommand()); 644 } 645 break; 646 case S_BUILD_COMMAND : 647 if (elementName.equals(NAME)) { 648 state = S_BUILD_COMMAND_NAME; 649 } else if (elementName.equals(BUILD_TRIGGERS)) { 650 state = S_BUILD_COMMAND_TRIGGERS; 651 } else if (elementName.equals(ARGUMENTS)) { 652 state = S_BUILD_COMMAND_ARGUMENTS; 653 objectStack.push(new HashMap()); 656 } 657 break; 658 case S_BUILD_COMMAND_ARGUMENTS : 659 if (elementName.equals(DICTIONARY)) { 660 state = S_DICTIONARY; 661 objectStack.push(new String ()); objectStack.push(new String ()); } 665 break; 666 case S_DICTIONARY : 667 if (elementName.equals(KEY)) { 668 state = S_DICTIONARY_KEY; 669 } else if (elementName.equals(VALUE)) { 670 state = S_DICTIONARY_VALUE; 671 } 672 break; 673 case S_NATURES : 674 if (elementName.equals(NATURE)) { 675 state = S_NATURE_NAME; 676 } 677 break; 678 case S_LINKED_RESOURCES : 679 if (elementName.equals(LINK)) { 680 state = S_LINK; 681 objectStack.push(new LinkDescription()); 684 } 685 break; 686 case S_LINK : 687 if (elementName.equals(NAME)) { 688 state = S_LINK_PATH; 689 } else if (elementName.equals(TYPE)) { 690 state = S_LINK_TYPE; 691 } else if (elementName.equals(LOCATION)) { 692 state = S_LINK_LOCATION; 693 } else if (elementName.equals(LOCATION_URI)) { 694 state = S_LINK_LOCATION_URI; 695 } 696 break; 697 } 698 } 699 700 703 public void warning(SAXParseException error) { 704 log(error); 705 } 706 } 707 | Popular Tags |