KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > emf > mapping > command > PersistentCommandStack


1 /**
2  * <copyright>
3  *
4  * Copyright (c) 2002-2004 IBM Corporation and others.
5  * All rights reserved. This program and the accompanying materials
6  * are made available under the terms of the Eclipse Public License v1.0
7  * which accompanies this distribution, and is available at
8  * http://www.eclipse.org/legal/epl-v10.html
9  *
10  * Contributors:
11  * IBM - Initial API and implementation
12  *
13  * </copyright>
14  *
15  * $Id: PersistentCommandStack.java,v 1.3 2005/06/12 13:38:46 emerks Exp $
16  */

17 package org.eclipse.emf.mapping.command;
18
19
20 import java.util.ArrayList JavaDoc;
21 import java.util.Collection JavaDoc;
22 import java.util.HashMap JavaDoc;
23 import java.util.Iterator JavaDoc;
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 /**
42  * This implementation of a command stack records the command class and command parameter used to create each command.
43  * This information can be used to create and execute all the commands again in a different session.
44  */

45 public class PersistentCommandStack extends BasicCommandStack
46 {
47   /**
48    * This keeps track of the mapping between commands and their {@link CommandCreationRecord}s.
49    */

50   protected HashMap JavaDoc commandCreationMap = new HashMap JavaDoc();
51
52   protected MappingDomain domain;
53   protected ClassLoader JavaDoc classLoader;
54   protected String JavaDoc encoding;
55
56   /**
57    * This constructs and instance of a command stack that records commands using a persistent encoding.
58    */

59   public PersistentCommandStack(ClassLoader JavaDoc classLoader)
60   {
61     super();
62     this.classLoader = classLoader;
63   }
64
65   /**
66    * This is called by the mapping domain whenever a command (that may subsequently be executed) is created.
67    */

68   public void handleCreateCommand(Class JavaDoc commandClass, CommandParameter commandParameter, Command command)
69   {
70     // Just remember it; it's encoded later during execution, which is more efficient.
71
//
72
CommandCreationRecord commandCreationRecord = new CommandCreationRecord(commandClass, commandParameter);
73     commandCreationMap.put(command, commandCreationRecord);
74   }
75
76   /**
77    * You can overide this to create your own type of encoder.
78    */

79   protected Encoder createEncoder()
80   {
81     return new Encoder();
82   }
83
84   /**
85    * You can overide this to create your own type of decoder.
86    */

87   protected Decoder createDecoder(MappingRoot mappingRoot, ResourceSet resourceSet, ClassLoader JavaDoc classLoader)
88   {
89     return new Decoder(mappingRoot, resourceSet, classLoader);
90   }
91
92   /**
93    * This override of execute calls {@link CommandCreationRecord#encode} just before normal execution by super.
94    */

95   public void execute(Command command)
96   {
97     CommandCreationRecord commandCreationRecord = (CommandCreationRecord)commandCreationMap.get(command);
98     if (commandCreationRecord != null)
99     {
100       // Do the encoding.
101
//
102
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 JavaDoc getEncoding()
120   {
121     // Record the records for the executed commands on the stack.
122
//
123
Collection JavaDoc commandCreationRecordList = new ArrayList JavaDoc();
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 JavaDoc 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 JavaDoc commandCreationRecordList = (Collection JavaDoc)decoder.decode();
156     if (commandCreationRecordList != null)
157     {
158       boolean failure = false;
159       for (Iterator JavaDoc 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 JavaDoc buffer;
189
190     public Encoder()
191     {
192       this.buffer = new StringBuffer JavaDoc();
193     }
194
195     public Encoder(StringBuffer JavaDoc buffer)
196     {
197       this.buffer = buffer;
198     }
199
200     public void setBuffer(StringBuffer JavaDoc 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 JavaDoc object)
216     {
217       if (object == null)
218       {
219         buffer.append("<null/>");
220        }
221       else if (object instanceof Class JavaDoc)
222       {
223         Class JavaDoc theClass = (Class JavaDoc)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 JavaDoc mappedObjects = mapping.getMappedObjects();
247             Collection JavaDoc collection = mappingRoot.getExactMappings(mappedObjects);
248
249             // If there is more than one exact match, we must get an index number;
250
//
251
int index = 0;
252             if (collection.size() > 1)
253             {
254               // Iterate over the whole tree to do this.
255
//
256
for (TreeIterator mappings = mappingRoot.treeIterator(); mappings.hasNext(); )
257               {
258                 Object JavaDoc 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           //if (resource != null)
283
{
284             //Resource resource = EcoreUtil.getURI(refObject).; FIX:::
285
String JavaDoc href = EcoreUtil.getURI(refObject).toString();
286             buffer.append("<ref-object HREF=\"" + href + "\"/>");
287           }
288           /*else if (refObject.refPackage() != null && refObject instanceof EStructuralFeature)
289           {
290             EPackage refPackage = refObject.refPackage();
291             buffer.append("<ref_structural-feature ");
292             buffer.append("package-name=\"" + refPackage.refNamespaceURI() + "\" ");
293             buffer.append("meta-object-name=\"" + refObject.refContainer().refName() + "\" ");
294             buffer.append("meta-feature-name=\"" + refObject.refName() + "\"");
295             buffer.append("/>");
296           }
297           else
298           {
299             buffer.append("<null/>");
300           }*/

301         }
302       }
303       else if (object instanceof Collection JavaDoc)
304       {
305         Collection JavaDoc collection = (Collection JavaDoc)object;
306         buffer.append("<collection>");
307         for (Iterator JavaDoc objects = collection.iterator(); objects.hasNext(); )
308         {
309           Object JavaDoc member = objects.next();
310           encode(member);
311         }
312         buffer.append("</collection>");
313       }
314       else if (object instanceof String JavaDoc)
315       {
316         buffer.append("<string value=\"" + (String JavaDoc)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 JavaDoc toString()
341     {
342       return buffer.toString();
343     }
344   }
345   
346   public static class Decoder
347   {
348     protected String JavaDoc string;
349     protected int index = 0;
350     protected ResourceSet resourceSet;
351     protected ClassLoader JavaDoc classLoader;
352     protected MappingRoot mappingRoot;
353
354     public Decoder(MappingRoot mappingRoot, ResourceSet resourceSet, ClassLoader JavaDoc classLoader)
355     {
356       this.mappingRoot = mappingRoot;
357       this.resourceSet = resourceSet;
358       this.classLoader = classLoader;
359     }
360
361     public void setEncoding(String JavaDoc 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 JavaDoc decode()
376     {
377       Object JavaDoc 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 JavaDoc 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 JavaDoc className = string.substring(classIndex, index);
406           index = string.indexOf(">", index) + 1;
407
408           try
409           {
410             result = classLoader.loadClass(className);
411           }
412           catch (Exception JavaDoc 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 JavaDoc)decode()).floatValue();
422           int operations = ((Integer JavaDoc)decode()).intValue();
423           int operation = ((Integer JavaDoc)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 JavaDoc owner = decode();
434           Object JavaDoc feature = decode();
435           Collection JavaDoc collection = (Collection JavaDoc)decode();
436           Object JavaDoc value = decode();
437           int theIndex = ((Integer JavaDoc)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 JavaDoc 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 JavaDoc packageURI = string.substring(startIndex, index);
479
480           index = string.indexOf("\"", index + 1);
481           startIndex = ++index;
482           index = string.indexOf("\"", index);
483           String JavaDoc metaObjectName = string.substring(startIndex, index);
484
485           index = string.indexOf("\"", index + 1);
486           startIndex = ++index;
487           index = string.indexOf("\"", index);
488           String JavaDoc 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 JavaDoc mappedObjects = (Collection JavaDoc)decode();
501           int value = ((Integer JavaDoc)decode()).intValue();
502           index = string.indexOf(">", index) + 1;
503
504           Collection JavaDoc collection = mappingRoot.getExactMappings(mappedObjects);
505           if (collection.size() > 1)
506           {
507             // Iterate over the whole tree to do this.
508
//
509
for (TreeIterator mappings = mappingRoot.treeIterator(); mappings.hasNext(); )
510             {
511               Object JavaDoc 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 JavaDoc collection = new ArrayList JavaDoc();
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 JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc 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         // System.out.println("Decoded key= '" + key + "':'" + string.substring(resultStartIndex, index) + "'");
599

600         skipWhitespace();
601       }
602
603       return result;
604     }
605
606     public String JavaDoc toString()
607     {
608       return index < string.length() ? string.substring(index) : "";
609     }
610   }
611
612   /**
613    * This records and encodes the command class and command parameter.
614    */

615   public static class CommandCreationRecord
616   {
617     Class JavaDoc commandClass;
618     CommandParameter commandParameter;
619     String JavaDoc encoding;
620
621     public CommandCreationRecord(Class JavaDoc commandClass, CommandParameter commandParameter)
622     {
623       this.commandClass = commandClass;
624       this.commandParameter = commandParameter;
625       this.encoding = null;
626     }
627
628     public CommandCreationRecord(String JavaDoc encoding)
629     {
630       this.encoding = encoding;
631     }
632
633     public CommandParameter getCommandParameter()
634     {
635       return commandParameter;
636     }
637
638     public String JavaDoc getEncoding()
639     {
640       return encoding;
641     }
642
643     public Class JavaDoc 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 JavaDoc)decoder.decode();
659       commandParameter = (CommandParameter)decoder.decode();
660     }
661     
662     public String JavaDoc toString()
663     {
664       return
665         "CommandCreationRecord { commandClass=" +
666           (commandClass == null ? "null" : commandClass.getName()) +
667           ", commandParameter=" + commandParameter + " }";
668     }
669   }
670 }
671
Popular Tags