1 17 package org.eclipse.emf.mapping.command; 18 19 20 import java.util.ArrayList ; 21 import java.util.Collection ; 22 import java.util.HashMap ; 23 import java.util.Iterator ; 24 25 import org.eclipse.emf.common.command.BasicCommandStack; 26 import org.eclipse.emf.common.command.Command; 27 import org.eclipse.emf.common.util.TreeIterator; 28 import org.eclipse.emf.common.util.URI; 29 import org.eclipse.emf.ecore.EClass; 30 import org.eclipse.emf.ecore.EObject; 31 import org.eclipse.emf.ecore.EPackage; 32 import org.eclipse.emf.ecore.resource.ResourceSet; 33 import org.eclipse.emf.ecore.util.EcoreUtil; 34 import org.eclipse.emf.edit.command.CommandParameter; 35 import org.eclipse.emf.edit.command.DragAndDropCommand; 36 import org.eclipse.emf.mapping.Mapping; 37 import org.eclipse.emf.mapping.MappingRoot; 38 import org.eclipse.emf.mapping.domain.MappingDomain; 39 40 41 45 public class PersistentCommandStack extends BasicCommandStack 46 { 47 50 protected HashMap commandCreationMap = new HashMap (); 51 52 protected MappingDomain domain; 53 protected ClassLoader classLoader; 54 protected String encoding; 55 56 59 public PersistentCommandStack(ClassLoader classLoader) 60 { 61 super(); 62 this.classLoader = classLoader; 63 } 64 65 68 public void handleCreateCommand(Class commandClass, CommandParameter commandParameter, Command command) 69 { 70 CommandCreationRecord commandCreationRecord = new CommandCreationRecord(commandClass, commandParameter); 73 commandCreationMap.put(command, commandCreationRecord); 74 } 75 76 79 protected Encoder createEncoder() 80 { 81 return new Encoder(); 82 } 83 84 87 protected Decoder createDecoder(MappingRoot mappingRoot, ResourceSet resourceSet, ClassLoader classLoader) 88 { 89 return new Decoder(mappingRoot, resourceSet, classLoader); 90 } 91 92 95 public void execute(Command command) 96 { 97 CommandCreationRecord commandCreationRecord = (CommandCreationRecord)commandCreationMap.get(command); 98 if (commandCreationRecord != null) 99 { 100 commandCreationRecord.encode(createEncoder()); 103 System.out.println("Executing Encoded Command: " + commandCreationRecord.getEncoding()); 104 } 105 else 106 { 107 System.out.println("Executing Unregistered Command: " + command); 108 Thread.dumpStack(); 109 } 110 111 super.execute(command); 112 113 if (encoding != null) 114 { 115 executeEncoding(); 116 } 117 } 118 119 public String getEncoding() 120 { 121 Collection commandCreationRecordList = new ArrayList (); 124 125 for (int i = 0; i <= top; ++i) 126 { 127 CommandCreationRecord commandCreationRecord = (CommandCreationRecord)commandCreationMap.get(commandList.get(i)); 128 if (commandCreationRecord == null) 129 { 130 System.out.println("UnregisteredCommand:" + commandList.get(i)); 131 break; 132 } 133 else if (commandCreationRecord.getCommandClass() != RestoreInitialStateCommand.class) 134 { 135 commandCreationRecordList.add(commandCreationRecord); 136 } 137 } 138 139 Encoder encoder = createEncoder(); 140 encoder.encode(commandCreationRecordList); 141 return encoder.toString(); 142 } 143 144 public void setEncoding(MappingDomain domain, String encoding) 145 { 146 this.domain = domain; 147 this.encoding = encoding; 148 } 149 150 protected void executeEncoding() 151 { 152 Decoder decoder = createDecoder(domain.getMappingRoot(), domain.getResourceSet(), classLoader); 153 decoder.setEncoding(encoding); 154 encoding = null; 155 Collection commandCreationRecordList = (Collection )decoder.decode(); 156 if (commandCreationRecordList != null) 157 { 158 boolean failure = false; 159 for (Iterator commandCreationRecords = commandCreationRecordList.iterator(); commandCreationRecords.hasNext(); ) 160 { 161 CommandCreationRecord commandCreationRecord = (CommandCreationRecord)commandCreationRecords.next(); 162 commandCreationRecord.decode(decoder); 163 164 Command command =domain.createCommand(commandCreationRecord.getCommandClass(), commandCreationRecord.getCommandParameter()); 165 if (command.canExecute()) 166 { 167 System.out.println("Re-executed Command: " + command); 168 execute(command); 169 } 170 else 171 { 172 System.out.println("Not! Executing Command: " + command); 173 command.dispose(); 174 failure = true; 175 break; 176 } 177 } 178 179 if (!failure) 180 { 181 saveIsDone(); 182 } 183 } 184 } 185 186 public static class Encoder 187 { 188 protected StringBuffer buffer; 189 190 public Encoder() 191 { 192 this.buffer = new StringBuffer (); 193 } 194 195 public Encoder(StringBuffer buffer) 196 { 197 this.buffer = buffer; 198 } 199 200 public void setBuffer(StringBuffer buffer) 201 { 202 this.buffer = buffer; 203 } 204 205 public void encode(int value) 206 { 207 buffer.append("<int value=\"" + value + "\"/>"); 208 } 209 210 public void encode(float value) 211 { 212 buffer.append("<float value=\"" + value + "\"/>"); 213 } 214 215 public void encode(Object object) 216 { 217 if (object == null) 218 { 219 buffer.append("<null/>"); 220 } 221 else if (object instanceof Class ) 222 { 223 Class theClass = (Class )object; 224 buffer.append("<class name=\"" + theClass.getName() + "\"/>"); 225 } 226 else if (object instanceof CommandParameter) 227 { 228 CommandParameter commandParameter = (CommandParameter)object; 229 buffer.append("<command-parameter>"); 230 encode(commandParameter.getOwner()); 231 encode(commandParameter.getFeature()); 232 encode(commandParameter.getCollection()); 233 encode(commandParameter.getValue()); 234 encode(commandParameter.getIndex()); 235 buffer.append("</command-parameter>"); 236 } 237 else if (object instanceof EObject) 238 { 239 if (object instanceof Mapping) 240 { 241 Mapping mapping = (Mapping)object; 242 MappingRoot mappingRoot = mapping.getMappingRoot(); 243 244 if (mappingRoot != null) 245 { 246 Collection mappedObjects = mapping.getMappedObjects(); 247 Collection collection = mappingRoot.getExactMappings(mappedObjects); 248 249 int index = 0; 252 if (collection.size() > 1) 253 { 254 for (TreeIterator mappings = mappingRoot.treeIterator(); mappings.hasNext(); ) 257 { 258 Object otherMapping = mappings.next(); 259 if (otherMapping == mapping) 260 { 261 break; 262 } 263 else if (collection.contains(otherMapping)) 264 { 265 ++index; 266 } 267 } 268 } 269 buffer.append("<mapping>"); 270 encode(mappedObjects); 271 encode(index); 272 buffer.append("</mapping>"); 273 } 274 else 275 { 276 buffer.append("<null/>"); 277 } 278 } 279 else 280 { 281 EObject refObject = (EObject)object; 282 { 284 String href = EcoreUtil.getURI(refObject).toString(); 286 buffer.append("<ref-object HREF=\"" + href + "\"/>"); 287 } 288 301 } 302 } 303 else if (object instanceof Collection ) 304 { 305 Collection collection = (Collection )object; 306 buffer.append("<collection>"); 307 for (Iterator objects = collection.iterator(); objects.hasNext(); ) 308 { 309 Object member = objects.next(); 310 encode(member); 311 } 312 buffer.append("</collection>"); 313 } 314 else if (object instanceof String ) 315 { 316 buffer.append("<string value=\"" + (String )object + "\"/>"); 317 } 318 else if (object instanceof DragAndDropCommand.Detail) 319 { 320 DragAndDropCommand.Detail detail = (DragAndDropCommand.Detail)object; 321 buffer.append("<drag-and-drop-detail>"); 322 encode(detail.location); 323 encode(detail.operations); 324 encode(detail.operation); 325 buffer.append("</drag-and-drop-detail>"); 326 } 327 else if (object instanceof CommandCreationRecord) 328 { 329 CommandCreationRecord commandCreationRecord = (CommandCreationRecord)object; 330 buffer.append("<command-creation-record>"); 331 buffer.append(commandCreationRecord.getEncoding()); 332 buffer.append("</command-creation-record>"); 333 } 334 else 335 { 336 buffer.append("<unknown>" + object.toString() + "</unknown>"); 337 } 338 } 339 340 public String toString() 341 { 342 return buffer.toString(); 343 } 344 } 345 346 public static class Decoder 347 { 348 protected String string; 349 protected int index = 0; 350 protected ResourceSet resourceSet; 351 protected ClassLoader classLoader; 352 protected MappingRoot mappingRoot; 353 354 public Decoder(MappingRoot mappingRoot, ResourceSet resourceSet, ClassLoader classLoader) 355 { 356 this.mappingRoot = mappingRoot; 357 this.resourceSet = resourceSet; 358 this.classLoader = classLoader; 359 } 360 361 public void setEncoding(String encoding) 362 { 363 string = encoding; 364 index = 0; 365 } 366 367 protected void skipWhitespace() 368 { 369 while (index < string.length() && Character.isWhitespace(string.charAt(index))) 370 { 371 ++index; 372 } 373 } 374 375 public Object decode() 376 { 377 Object result = null; 378 379 skipWhitespace(); 380 if (index < string.length() && string.charAt(index) == '<') 381 { 382 ++index; 383 skipWhitespace(); 384 int keyStartIndex = index; 385 while (index < string.length() && 386 !Character.isWhitespace(string.charAt(index)) && 387 string.charAt(index) != '/' && 388 string.charAt(index) != '>') 389 { 390 ++index; 391 } 392 String key = string.substring(keyStartIndex, index); 393 394 if (key.equals("null")) 395 { 396 index = string.indexOf(">", index) + 1; 397 result = null; 398 } 399 else if (key.equals("class")) 400 { 401 index = string.indexOf("\"", index); 402 int classIndex = ++index; 403 index = string.indexOf("\"", index); 404 405 String className = string.substring(classIndex, index); 406 index = string.indexOf(">", index) + 1; 407 408 try 409 { 410 result = classLoader.loadClass(className); 411 } 412 catch (Exception exception) 413 { 414 exception.printStackTrace(); 415 } 416 } 417 else if (key.equals("drag-and-drop-detail")) 418 { 419 index = string.indexOf(">", index) + 1; 420 421 float location = ((Float )decode()).floatValue(); 422 int operations = ((Integer )decode()).intValue(); 423 int operation = ((Integer )decode()).intValue(); 424 425 index = string.indexOf(">", index) + 1; 426 427 result = new DragAndDropCommand.Detail(location, operations, operation); 428 } 429 else if (key.equals("command-parameter")) 430 { 431 index = string.indexOf(">", index) + 1; 432 433 Object owner = decode(); 434 Object feature = decode(); 435 Collection collection = (Collection )decode(); 436 Object value = decode(); 437 int theIndex = ((Integer )decode()).intValue(); 438 439 index = string.indexOf(">", index) + 1; 440 441 if (collection == null) 442 { 443 result = new CommandParameter(owner, feature, value, theIndex); 444 } 445 else 446 { 447 result = new CommandParameter(owner, feature, collection, theIndex); 448 } 449 } 450 else if (key.equals("command-creation-record")) 451 { 452 index = string.indexOf(">", index) + 1; 453 454 int startIndex = index; 455 456 index = string.indexOf("</command-creation-record>", index); 457 index = string.indexOf(">", index) + 1; 458 459 result = new CommandCreationRecord(string.substring(startIndex, index)); 460 } 461 else if (key.equals("ref-object")) 462 { 463 index = string.indexOf("\"", index); 464 int hrefStartIndex = ++index; 465 index = string.indexOf("\"", index); 466 467 String href = string.substring(hrefStartIndex, index); 468 469 index = string.indexOf(">", index) + 1; 470 471 result = resourceSet.getEObject(URI.createURI(href), true); 472 } 473 else if (key.equals("ref_structural-feature")) 474 { 475 index = string.indexOf("\"", index); 476 int startIndex = ++index; 477 index = string.indexOf("\"", index); 478 String packageURI = string.substring(startIndex, index); 479 480 index = string.indexOf("\"", index + 1); 481 startIndex = ++index; 482 index = string.indexOf("\"", index); 483 String metaObjectName = string.substring(startIndex, index); 484 485 index = string.indexOf("\"", index + 1); 486 startIndex = ++index; 487 index = string.indexOf("\"", index); 488 String metaFeatureName = string.substring(startIndex, index); 489 490 index = string.indexOf(">", index) + 1; 491 492 EPackage refPackage = EPackage.Registry.INSTANCE.getEPackage(packageURI); 493 EClass metaObject = (EClass)refPackage.getEClassifier(metaObjectName); 494 EObject metaFeature = metaObject.getEStructuralFeature(metaFeatureName); 495 result = metaFeature; 496 } 497 else if (key.equals("mapping")) 498 { 499 index = string.indexOf(">", index) + 1; 500 Collection mappedObjects = (Collection )decode(); 501 int value = ((Integer )decode()).intValue(); 502 index = string.indexOf(">", index) + 1; 503 504 Collection collection = mappingRoot.getExactMappings(mappedObjects); 505 if (collection.size() > 1) 506 { 507 for (TreeIterator mappings = mappingRoot.treeIterator(); mappings.hasNext(); ) 510 { 511 Object mapping = mappings.next(); 512 if (collection.contains(mapping)) 513 { 514 if (value == 0) 515 { 516 result = mapping; 517 break; 518 } 519 else 520 { 521 --value; 522 } 523 } 524 } 525 } 526 527 if (result == null && !collection.isEmpty()) 528 { 529 result = collection.iterator().next(); 530 } 531 } 532 else if (key.equals("collection")) 533 { 534 Collection collection = new ArrayList (); 535 536 index = string.indexOf(">", index) + 1; 537 538 while (index < string.length() && Character.isWhitespace(string.charAt(index))) 539 { 540 ++index; 541 } 542 543 while (index < string.length() && string.indexOf("</collection>", index) != index) 544 { 545 Object object = decode(); 546 collection.add(object); 547 while (index < string.length() && Character.isWhitespace(string.charAt(index))) 548 { 549 ++index; 550 } 551 } 552 553 if (index < string.length()) 554 { 555 index += "</collection>".length(); 556 } 557 558 result = collection; 559 } 560 else if (key.equals("string")) 561 { 562 index = string.indexOf("\"", index); 563 int startIndex = ++index; 564 index = string.indexOf("\"", index); 565 String value = string.substring(startIndex, index); 566 567 index = string.indexOf(">", index) + 1; 568 569 result = value; 570 } 571 else if (key.equals("int")) 572 { 573 index = string.indexOf("\"", index); 574 int startIndex = ++index; 575 index = string.indexOf("\"", index); 576 String value = string.substring(startIndex, index); 577 578 index = string.indexOf(">", index) + 1; 579 580 result = Integer.valueOf(value); 581 } 582 else if (key.equals("float")) 583 { 584 index = string.indexOf("\"", index); 585 int startIndex = ++index; 586 index = string.indexOf("\"", index); 587 String value = string.substring(startIndex, index); 588 589 index = string.indexOf(">", index) + 1; 590 591 result = Float.valueOf(value); 592 } 593 else 594 { 595 index = string.indexOf("</unknown>", index) + "</unknown>".length(); 596 } 597 598 600 skipWhitespace(); 601 } 602 603 return result; 604 } 605 606 public String toString() 607 { 608 return index < string.length() ? string.substring(index) : ""; 609 } 610 } 611 612 615 public static class CommandCreationRecord 616 { 617 Class commandClass; 618 CommandParameter commandParameter; 619 String encoding; 620 621 public CommandCreationRecord(Class commandClass, CommandParameter commandParameter) 622 { 623 this.commandClass = commandClass; 624 this.commandParameter = commandParameter; 625 this.encoding = null; 626 } 627 628 public CommandCreationRecord(String encoding) 629 { 630 this.encoding = encoding; 631 } 632 633 public CommandParameter getCommandParameter() 634 { 635 return commandParameter; 636 } 637 638 public String getEncoding() 639 { 640 return encoding; 641 } 642 643 public Class getCommandClass() 644 { 645 return commandClass; 646 } 647 648 public void encode(Encoder encoder) 649 { 650 encoder.encode(commandClass); 651 encoder.encode(commandParameter); 652 encoding = encoder.toString(); 653 } 654 655 public void decode(Decoder decoder) 656 { 657 decoder.setEncoding(encoding); 658 commandClass = (Class )decoder.decode(); 659 commandParameter = (CommandParameter)decoder.decode(); 660 } 661 662 public String toString() 663 { 664 return 665 "CommandCreationRecord { commandClass=" + 666 (commandClass == null ? "null" : commandClass.getName()) + 667 ", commandParameter=" + commandParameter + " }"; 668 } 669 } 670 } 671 | Popular Tags |