1 11 12 package org.eclipse.ant.internal.ui.antsupport.logger.util; 13 14 import java.util.HashMap ; 15 import java.util.Hashtable ; 16 import java.util.Iterator ; 17 import java.util.Map ; 18 import java.util.Stack ; 19 import java.util.Vector ; 20 21 import org.apache.tools.ant.BuildEvent; 22 import org.apache.tools.ant.Location; 23 import org.apache.tools.ant.Project; 24 import org.apache.tools.ant.Target; 25 import org.apache.tools.ant.Task; 26 import org.apache.tools.ant.taskdefs.MacroInstance; 27 28 public class AntDebugState { 29 30 private static final String fgAntTaskName= "ant"; private static final String fgAntCallTaskName= "antcall"; 33 private IDebugBuildLogger fLogger; 34 private Stack fTasks= new Stack (); 35 private Map fTaskToProxies= new HashMap (); 36 private Task fCurrentTask; 37 private Task fStepOverTask; 38 private Task fStepIntoTask; 39 private Task fLastTaskFinished; 40 41 private Map fInitialProperties= null; 43 private Map fProperties= null; 44 45 private Map fProjectToTargetNames= null; 46 private Map fProjectToMapOfTargetToBuildSequence= null; 47 private Stack fTargetsToExecute= new Stack (); 48 private Stack fTargetsExecuting= new Stack (); 49 50 private boolean fConsiderTargetBreakpoints= false; 51 private boolean fShouldSuspend; 52 private boolean fClientSuspend= false; 53 private boolean fStepIntoSuspend= false; 54 private boolean fIsAfterTaskEvent= false; 55 56 57 public AntDebugState(IDebugBuildLogger logger) { 58 fLogger= logger; 59 } 60 61 public void waitIfSuspended() { 62 fLogger.waitIfSuspended(); 63 } 64 65 public Task getLastTaskFinished() { 66 return fLastTaskFinished; 67 } 68 69 private void setLastTaskFinished(Task lastTaskFinished) { 70 fLastTaskFinished= lastTaskFinished; 71 72 } 73 74 public Task getCurrentTask() { 75 return fCurrentTask; 76 } 77 78 public void setCurrentTask(Task currentTask) { 79 fCurrentTask= currentTask; 80 81 } 82 83 private Map getInitialProperties() { 84 return fInitialProperties; 85 } 86 87 public Task getStepOverTask() { 88 return fStepOverTask; 89 } 90 91 public void setStepOverTask(Task stepOverTask) { 92 fStepOverTask= stepOverTask; 93 94 } 95 96 private boolean considerTargetBreakpoints() { 97 return fConsiderTargetBreakpoints; 98 } 99 100 private void setConsiderTargetBreakpoints(boolean considerTargetBreakpoints) { 101 fConsiderTargetBreakpoints= considerTargetBreakpoints; 102 } 103 104 private Stack getTasks() { 105 return fTasks; 106 } 107 108 public void setShouldSuspend(boolean shouldSuspend) { 109 fShouldSuspend= shouldSuspend; 110 } 111 112 public boolean shouldSuspend() { 113 return fShouldSuspend; 114 } 115 116 private Map getTargetToBuildSequence(Project project) { 117 return (Map ) fProjectToMapOfTargetToBuildSequence.get(project); 118 } 119 120 public void setTargetToExecute(Target target) { 121 if (target == null) { 122 fTargetsToExecute.pop(); 123 } else { 124 fTargetsToExecute.push(target); 125 } 126 } 127 128 public void setTargetExecuting(Target target) { 129 if (target == null) { 130 fTargetsExecuting.pop(); 131 } else { 132 fTargetsExecuting.push(target); 133 } 134 } 135 136 private Target getTargetToExecute() { 137 if (fTargetsToExecute.isEmpty()) { 138 return null; 139 } 140 return (Target) fTargetsToExecute.peek(); 141 } 142 143 private Target getTargetExecuting() { 144 if (fTargetsExecuting.isEmpty()) { 145 return null; 146 } 147 return (Target) fTargetsExecuting.peek(); 148 } 149 150 public boolean isStepIntoSuspend() { 151 return isAfterTaskEvent() && fStepIntoSuspend; 152 } 153 154 public void setStepIntoSuspend(boolean stepIntoSuspend) { 155 fStepIntoSuspend = stepIntoSuspend; 156 } 157 158 public boolean isClientSuspend() { 159 return fClientSuspend; 160 } 161 162 public void setClientSuspend(boolean clientSuspend) { 163 fClientSuspend = clientSuspend; 164 } 165 166 public Task getStepIntoTask() { 167 return fStepIntoTask; 168 } 169 170 public void setStepIntoTask(Task stepIntoTask) { 171 fStepIntoTask = stepIntoTask; 172 } 173 174 public void resume() { 175 fLogger.notifyAll(); 176 } 177 178 public Map getProperties() { 179 return fProperties; 180 } 181 182 public Location getBreakpointLocation() { 183 if (isAfterTaskEvent() && getCurrentTask() != null) { 184 return getCurrentTask().getLocation(); 185 } 186 if (considerTargetBreakpoints()) { 187 Target targetExecuting= getTargetExecuting(); 188 if (targetExecuting != null) { 189 return getLocation(targetExecuting); 190 } 191 } 192 return null; 193 } 194 195 private boolean isAfterTaskEvent() { 196 return fIsAfterTaskEvent; 197 } 198 199 private void setAfterTaskEvent(boolean isAfterTaskEvent) { 200 fIsAfterTaskEvent = isAfterTaskEvent; 201 } 202 203 public void taskStarted(BuildEvent event) { 204 setAfterTaskEvent(true); 205 if (getInitialProperties() == null) { fInitialProperties= event.getProject().getProperties(); 207 } 208 209 setCurrentTask(event.getTask()); 210 setConsiderTargetBreakpoints(false); 211 if (!getTasks().isEmpty()) { 212 Task parentTask = (Task) getTasks().peek(); 215 Object proxy = parentTask.getRuntimeConfigurableWrapper().getProxy(); 216 if (proxy != null) { 217 fTaskToProxies.put(parentTask, proxy); 218 } 219 } 220 getTasks().push(getCurrentTask()); 221 waitIfSuspended(); 222 } 223 224 225 public void taskFinished() { 226 Task lastTask= (Task)getTasks().pop(); 227 setLastTaskFinished(lastTask); 228 setCurrentTask(null); 229 String taskName= lastTask.getTaskName(); 230 231 if (getStepOverTask() != null) { 232 if ((fgAntCallTaskName.equals(taskName) || fgAntTaskName.equals(taskName)) && (!fgAntCallTaskName.equals(getStepOverTask().getTaskName()) && !fgAntTaskName.equals(getStepOverTask().getTaskName()))) { 233 setShouldSuspend(true); 234 } else if (fTaskToProxies.remove(lastTask) instanceof MacroInstance) { 235 setShouldSuspend(true); 236 } 237 } 238 waitIfSuspended(); 239 } 240 241 public void stepOver() { 242 setStepOverTask(getCurrentTask()); 243 if (getCurrentTask() == null) { 244 setShouldSuspend(true); 246 } 247 resume(); 248 } 249 250 public void targetStarted(BuildEvent event) { 251 setAfterTaskEvent(false); 252 Project eventProject = event.getProject(); 253 if (getInitialProperties() == null) { 254 fInitialProperties= eventProject.getProperties(); 255 } 256 if (fProjectToTargetNames.get(eventProject) == null) { 257 Object ref= eventProject.getReference("eclipse.ant.targetVector"); if (ref != null) { 259 fProjectToTargetNames.put(eventProject, ref); 260 Map targetToBuildSequence= new HashMap (); 261 setTargetToExecute(initializeBuildSequenceInformation(event, targetToBuildSequence)); 262 fProjectToMapOfTargetToBuildSequence.put(eventProject, targetToBuildSequence); 263 } 264 } 265 266 setTargetExecuting(event.getTarget()); 267 if (event.getTarget().equals(getTargetToExecute())) { 268 Vector targets= (Vector ) fProjectToTargetNames.get(eventProject); 271 if (!targets.isEmpty()) { 272 setTargetToExecute((Target) eventProject.getTargets().get(targets.remove(0))); 273 } else { 274 setTargetToExecute(null); 275 } 276 } 277 setConsiderTargetBreakpoints(true); 278 } 279 280 public int getLineNumber(Location location) { 281 try { return location.getLineNumber(); 283 } catch (NoSuchMethodError e) { 284 String locationString= location.toString(); 286 if (locationString.length() == 0) { 287 return 0; 288 } 289 int lastIndex= locationString.lastIndexOf(':'); 291 int index =locationString.lastIndexOf(':', lastIndex - 1); 292 if (index != -1) { 293 try { 294 return Integer.parseInt(locationString.substring(index+1, lastIndex)); 295 } catch (NumberFormatException nfe) { 296 return 0; 297 } 298 } 299 return 0; 300 } 301 } 302 303 public static Location getLocation(Target target) { 304 try { return target.getLocation(); 306 } catch (NoSuchMethodError e) { 307 return Location.UNKNOWN_LOCATION; 308 } 309 } 310 311 public String getFileName(Location location) { 312 try { return location.getFileName(); 314 } catch (NoSuchMethodError e) { 315 String locationString= location.toString(); 317 if (locationString.length() == 0) { 318 return null; 319 } 320 int lastIndex= locationString.lastIndexOf(':'); 322 int index =locationString.lastIndexOf(':', lastIndex-1); 323 if (index == -1) { 324 index= lastIndex; } 326 if (index != -1) { 327 return locationString.substring(5, index); 333 } 334 return null; 335 } 336 } 337 338 private void appendToStack(StringBuffer stackRepresentation, String targetName, String taskName, Location location) { 339 stackRepresentation.append(targetName); 340 stackRepresentation.append(DebugMessageIds.MESSAGE_DELIMITER); 341 stackRepresentation.append(taskName); 342 stackRepresentation.append(DebugMessageIds.MESSAGE_DELIMITER); 343 344 stackRepresentation.append(getFileName(location)); 345 stackRepresentation.append(DebugMessageIds.MESSAGE_DELIMITER); 346 stackRepresentation.append(getLineNumber(location)); 347 stackRepresentation.append(DebugMessageIds.MESSAGE_DELIMITER); 348 } 349 350 public void marshalStack(StringBuffer stackRepresentation) { 351 Stack tasks= getTasks(); 352 353 stackRepresentation.append(DebugMessageIds.STACK); 354 stackRepresentation.append(DebugMessageIds.MESSAGE_DELIMITER); 355 356 Target targetToExecute= getTargetToExecute(); 357 Target targetExecuting= getTargetExecuting(); 358 359 Project projectExecuting= null; 360 if (targetExecuting != null) { 361 projectExecuting= targetExecuting.getProject(); 362 } else { Task task= (Task) tasks.peek(); 364 projectExecuting= task.getProject(); 365 } 366 367 if (!isAfterTaskEvent()) { 368 appendToStack(stackRepresentation, targetExecuting.getName(), "", getLocation(targetExecuting)); } 370 for (int i = tasks.size() - 1; i >= 0 ; i--) { 371 Task task= (Task) tasks.get(i); 372 if (task.getProject() == projectExecuting) { 373 appendToStack(stackRepresentation, task.getOwningTarget().getName(), task.getTaskName(), task.getLocation()); 374 } else { 375 String targetName= task.getOwningTarget().getName(); 377 if (targetName != null && targetName.length() != 0) { Iterator itr= fTargetsToExecute.iterator(); 379 while (itr.hasNext()) { 380 Target target= (Target) itr.next(); 381 if (target.getProject() != projectExecuting) { 382 targetToExecute= target; 383 continue; 384 } 385 marshalTargetDependancyStack(stackRepresentation, target, targetExecuting); 386 } 387 } 388 projectExecuting= task.getProject(); 389 targetExecuting= task.getOwningTarget(); 390 appendToStack(stackRepresentation, targetExecuting.getName(), task.getTaskName(), task.getLocation()); 391 } 392 } 393 394 marshalTargetDependancyStack(stackRepresentation, targetToExecute, targetExecuting); 396 } 397 398 private void marshalTargetDependancyStack(StringBuffer stackRepresentation, Target targetToExecute, Target targetExecuting) { 399 if (targetToExecute != null) { 400 Vector buildSequence= (Vector ) getTargetToBuildSequence(targetToExecute.getProject()).get(targetToExecute); 401 int startIndex= buildSequence.indexOf(targetExecuting) + 1; 402 int dependancyStackDepth= buildSequence.indexOf(targetToExecute); 403 404 Target stackTarget; 405 for (int i = startIndex; i <= dependancyStackDepth; i++) { 406 stackTarget= (Target) buildSequence.get(i); 407 if (stackTarget.dependsOn(targetExecuting.getName())) { 408 appendToStack(stackRepresentation, stackTarget.getName(), "", getLocation(stackTarget)); } 410 } 411 } 412 } 413 414 public void marshallProperties(StringBuffer propertiesRepresentation, boolean escapeLineSep) { 415 if (getTasks().isEmpty()) { 416 return; 417 } 418 propertiesRepresentation.append(DebugMessageIds.PROPERTIES); 419 propertiesRepresentation.append(DebugMessageIds.MESSAGE_DELIMITER); 420 421 Project project= ((Task)getTasks().peek()).getProject(); 422 Map lastProperties= getProperties(); 423 424 Map currentProperties= project.getProperties(); 425 if (lastProperties != null && currentProperties.size() == lastProperties.size()) { 426 return; 428 } 429 430 Map initialProperties= getInitialProperties(); 431 Map currentUserProperties= project.getUserProperties(); 432 Iterator iter= currentProperties.keySet().iterator(); 433 String propertyName; 434 String originalPropertyName; 435 String propertyValue; 436 while (iter.hasNext()) { 437 propertyName = (String ) iter.next(); 438 originalPropertyName= propertyName; 439 if (lastProperties == null || lastProperties.get(propertyName) == null) { if (escapeLineSep) { 441 propertyName= escapeLineSeparator(propertyName); 442 } 443 propertiesRepresentation.append(propertyName.length()); 444 propertiesRepresentation.append(DebugMessageIds.MESSAGE_DELIMITER); 445 propertiesRepresentation.append(propertyName); 446 propertiesRepresentation.append(DebugMessageIds.MESSAGE_DELIMITER); 447 propertyValue= (String ) currentProperties.get(originalPropertyName); 448 if (escapeLineSep) { 449 propertyValue= escapeLineSeparator(propertyValue); 450 } 451 propertiesRepresentation.append(propertyValue.length()); 452 propertiesRepresentation.append(DebugMessageIds.MESSAGE_DELIMITER); 453 propertiesRepresentation.append(propertyValue); 454 propertiesRepresentation.append(DebugMessageIds.MESSAGE_DELIMITER); 455 propertiesRepresentation.append(getPropertyType(initialProperties, currentUserProperties, originalPropertyName)); 456 propertiesRepresentation.append(DebugMessageIds.MESSAGE_DELIMITER); 457 } 458 } 459 460 propertiesRepresentation.deleteCharAt(propertiesRepresentation.length() - 1); 461 fProperties= currentProperties; 462 } 463 464 private int getPropertyType(Map initialProperties, Map currentUserProperties, String propertyName) { 465 if (initialProperties.get(propertyName) != null) { if (currentUserProperties.get(propertyName) == null) { 467 return DebugMessageIds.PROPERTY_SYSTEM; 468 } 469 return DebugMessageIds.PROPERTY_USER; 470 } else if (currentUserProperties.get(propertyName) == null){ 471 return DebugMessageIds.PROPERTY_RUNTIME; 472 } else { 473 return DebugMessageIds.PROPERTY_USER; 474 } 475 } 476 477 private String escapeLineSeparator(String stringToEscape) { 478 if (!(stringToEscape.indexOf('\r') != -1 || stringToEscape.indexOf('\n') != -1 || stringToEscape.indexOf("\\r") != -1 || stringToEscape.indexOf("\\n") != -1)) { return stringToEscape; 480 } 481 StringBuffer escapedValue= new StringBuffer (stringToEscape); 482 for (int i= 0; i < escapedValue.length(); i++) { 483 switch (escapedValue.charAt(i)) { 484 case '\r': 485 escapedValue.replace(i, i+1, "\\r"); i++; 487 break; 488 case '\n': 489 escapedValue.replace(i, i+1, "\\n"); i++; 491 break; 492 case '\\': 493 if (escapedValue.charAt(i + 1) == 'r' || escapedValue.charAt(i + 1) == 'n') { 494 escapedValue.replace(i, i+1, "\\\\"); i++; 496 } 497 break; 498 default: 499 break; 500 } 501 } 502 503 return escapedValue.toString(); 504 } 505 506 private Target initializeBuildSequenceInformation(BuildEvent event, Map targetToBuildSequence) { 507 Project antProject= event.getProject(); 508 Vector targets= (Vector ) antProject.getReference("eclipse.ant.targetVector"); if (targets == null) { 510 return null; 511 } 512 Iterator itr= targets.iterator(); 513 Hashtable allTargets= antProject.getTargets(); 514 String targetName; 515 Vector sortedTargets; 516 while (itr.hasNext()) { 517 targetName= (String ) itr.next(); 518 sortedTargets= antProject.topoSort(targetName, allTargets); 519 targetToBuildSequence.put(allTargets.get(targetName), sortedTargets); 520 } 521 return (Target) allTargets.get(targets.remove(0)); 523 } 524 525 public void buildStarted() { 526 fProjectToTargetNames= new HashMap (); 527 fProjectToMapOfTargetToBuildSequence= new HashMap (); 528 } 529 } 530 | Popular Tags |