[jbosstools-commits] JBoss Tools SVN: r23381 - in branches/smooks-dmb: tests/org.jboss.tools.smooks.model.test/src/org/jboss/tools/smooks/model/command and 1 other directory.

jbosstools-commits at lists.jboss.org jbosstools-commits at lists.jboss.org
Tue Jul 13 03:32:13 EDT 2010


Author: DartPeng
Date: 2010-07-13 03:32:12 -0400 (Tue, 13 Jul 2010)
New Revision: 23381

Added:
   branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/CompositeCommand.java
   branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/ISmooksCommandStackChangeListener.java
   branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/SmooksCommandStackEvent.java
   branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/UnSetCommand.java
   branches/smooks-dmb/tests/org.jboss.tools.smooks.model.test/src/org/jboss/tools/smooks/model/command/CommandTest.java
Removed:
   branches/smooks-dmb/tests/org.jboss.tools.smooks.model.test/src/org/jboss/tools/smooks/model/command/SetCommandTest.java
Modified:
   branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/AddCommand.java
   branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/Command.java
   branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/ICommand.java
   branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/RemoveCommand.java
   branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/SetCommand.java
   branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/SmooksCommandStack.java
Log:


Modified: branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/AddCommand.java
===================================================================
--- branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/AddCommand.java	2010-07-13 06:46:00 UTC (rev 23380)
+++ branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/AddCommand.java	2010-07-13 07:32:12 UTC (rev 23381)
@@ -25,6 +25,7 @@
 
 	@Override
 	public void execute() {
+		if(!canExecute()) return;
 		try {
 			Object v = getPropertyValue();
 			if(!(v instanceof Collection)){
@@ -38,13 +39,13 @@
 	}
 
 	@Override
-	public boolean canExecute() {
-		return  ( host!=null && value!=null && !added && propertyName != null);
+	public String getCommandLabel() {
+		return "AddCommand";
 	}
 
 	@Override
-	public boolean canRedo() {
-		return super.canRedo();
+	public boolean canExecute() {
+		return  ( host!=null && value!=null && !added && propertyName != null);
 	}
 
 	@Override
@@ -54,6 +55,7 @@
 
 	@Override
 	public void undo() {
+		if(!canUndo()) return;
 		try {
 			Object v = getPropertyValue();
 			if(!(v instanceof Collection)){

Modified: branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/Command.java
===================================================================
--- branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/Command.java	2010-07-13 06:46:00 UTC (rev 23380)
+++ branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/Command.java	2010-07-13 07:32:12 UTC (rev 23381)
@@ -13,30 +13,29 @@
  * 
  */
 public class Command implements ICommand {
-	
+
 	protected Object host;
 
 	protected String propertyName;
-	
+
 	protected Object value;
-	
+
 	protected Object oldValue;
-	
-	protected boolean execued = false;
-	
-	protected boolean redoed = false;
-	
-	protected boolean undoed = false;
-	
-	public Command(){
-		
+
+
+	public Command() {
+
 	}
-	
-	public Command(Object host , Object value , String propertyName ){
+
+	public Command(Object host, Object value, String propertyName) {
 		this.host = host;
 		this.propertyName = propertyName;
 		this.value = value;
 	}
+	
+	public String getCommandLabel(){
+		return null;
+	}
 
 	public Object getValue() {
 		return value;
@@ -62,20 +61,31 @@
 		this.propertyName = propertyName;
 	}
 
-
-	protected Object getPropertyValue() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException{
+	protected Object getPropertyValue() throws IllegalAccessException,
+			InvocationTargetException, NoSuchMethodException {
 		return PropertyUtils.getProperty(host, propertyName);
 	}
-	
-	protected Method getSetterMethod() throws SecurityException, NoSuchMethodException{
+
+	protected Method getSetterMethod() throws SecurityException,
+			NoSuchMethodException {
 		char sc = propertyName.toCharArray()[0];
-		String us = new String(new char[]{sc});
+		String us = new String(new char[] { sc });
 		us = us.toUpperCase();
 		String n = propertyName.substring(1);
-		n = ("set" +us + n);
-		return host.getClass().getMethod(n, value.getClass());
+		n = ("set" + us + n);
+		if (value != null) {
+			return host.getClass().getMethod(n, value.getClass());
+		}else{
+			Method[] ms =  host.getClass().getMethods();
+			for (int i = 0; i < ms.length; i++) {
+				Method m = ms[i];
+				if(m.getName().equals(n)){
+					return m;
+				}
+			}
+		}
+		return null;
 	}
-	
 
 	/*
 	 * (non-Javadoc)
@@ -83,12 +93,12 @@
 	 * @see org.jboss.tools.smooks.model.command.ICommand#execute()
 	 */
 	public void execute() {
-//		if(!canExecute()) return;
+		// if(!canExecute()) return;
 		try {
 			oldValue = getPropertyValue();
 		} catch (Exception e) {
 			e.printStackTrace();
-		} 
+		}
 	}
 
 	/*
@@ -97,7 +107,7 @@
 	 * @see org.jboss.tools.smooks.model.command.ICommand#canExecute()
 	 */
 	public boolean canExecute() {
-		return ( host!=null && value!=null && !execued && propertyName != null);
+		return true;
 	}
 
 	/*
@@ -106,7 +116,7 @@
 	 * @see org.jboss.tools.smooks.model.command.ICommand#canRedo()
 	 */
 	public boolean canRedo() {
-		return ( host!=null && value!=null && execued && propertyName != null);
+		return true;
 	}
 
 	/*
@@ -115,7 +125,7 @@
 	 * @see org.jboss.tools.smooks.model.command.ICommand#canUndo()
 	 */
 	public boolean canUndo() {
-		return ( host!=null && execued && propertyName != null);
+		return true;
 	}
 
 	/*
@@ -133,12 +143,15 @@
 	 * @see org.jboss.tools.smooks.model.command.ICommand#undo()
 	 */
 	public void undo() {
-//		if(!canUndo()) return;
+		// if(!canUndo()) return;
 		try {
 			value = getPropertyValue();
 		} catch (Exception e) {
 			e.printStackTrace();
-		} 
+		}
 	}
 
+	public void dispose() {
+	}
+
 }

Added: branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/CompositeCommand.java
===================================================================
--- branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/CompositeCommand.java	                        (rev 0)
+++ branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/CompositeCommand.java	2010-07-13 07:32:12 UTC (rev 23381)
@@ -0,0 +1,116 @@
+/**
+ * 
+ */
+package org.jboss.tools.smooks.model.command;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * @author Dart
+ *
+ */
+public class CompositeCommand extends Command {
+
+	private List<ICommand> commandList = null;
+	
+	
+	public List<ICommand> getCommandList() {
+		if(commandList == null) commandList = new ArrayList<ICommand>();
+		return commandList;
+	}
+	
+	public void appendCommand(ICommand command){
+		getCommandList().add(command);
+	}
+	
+	public void removeCommand(ICommand command){
+		getCommandList().remove(command);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.jboss.tools.smooks.model.command.ICommand#execute()
+	 */
+	public void execute() {
+		List<ICommand> l = getCommandList();
+		for (Iterator<?> iterator = l.iterator(); iterator.hasNext();) {
+			ICommand iCommand = (ICommand) iterator.next();
+			iCommand.execute();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.jboss.tools.smooks.model.command.ICommand#canExecute()
+	 */
+	public boolean canExecute() {
+		List<ICommand> l = getCommandList();
+		for (Iterator<?> iterator = l.iterator(); iterator.hasNext();) {
+			ICommand iCommand = (ICommand) iterator.next();
+			if(!iCommand.canExecute()) return false; 
+		}
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.jboss.tools.smooks.model.command.ICommand#canRedo()
+	 */
+	public boolean canRedo() {
+		List<ICommand> l = getCommandList();
+		for (Iterator<?> iterator = l.iterator(); iterator.hasNext();) {
+			ICommand iCommand = (ICommand) iterator.next();
+			if(!iCommand.canRedo()) return false; 
+		}
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.jboss.tools.smooks.model.command.ICommand#canUndo()
+	 */
+	public boolean canUndo() {
+		List<ICommand> l = getCommandList();
+		for (Iterator<?> iterator = l.iterator(); iterator.hasNext();) {
+			ICommand iCommand = (ICommand) iterator.next();
+			if(!iCommand.canUndo()) return false; 
+		}
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.jboss.tools.smooks.model.command.ICommand#redo()
+	 */
+	public void redo() {
+		List<ICommand> l = getCommandList();
+		for (Iterator<?> iterator = l.iterator(); iterator.hasNext();) {
+			ICommand iCommand = (ICommand) iterator.next();
+			iCommand.redo();
+		}
+
+	}
+	
+	@Override
+	public String getCommandLabel() {
+		return "CompositeCommand";
+	}
+
+	/* (non-Javadoc)
+	 * @see org.jboss.tools.smooks.model.command.ICommand#undo()
+	 */
+	public void undo() {
+		List<ICommand> l = getCommandList();
+		for (Iterator<?> iterator = l.iterator(); iterator.hasNext();) {
+			ICommand iCommand = (ICommand) iterator.next();
+			iCommand.undo();
+		}
+
+	}
+
+	public void dispose() {
+		List<ICommand> l = getCommandList();
+		for (Iterator<?> iterator = l.iterator(); iterator.hasNext();) {
+			ICommand iCommand = (ICommand) iterator.next();
+			iCommand.dispose();
+		}
+	}
+
+}


Property changes on: branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/CompositeCommand.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Modified: branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/ICommand.java
===================================================================
--- branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/ICommand.java	2010-07-13 06:46:00 UTC (rev 23380)
+++ branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/ICommand.java	2010-07-13 07:32:12 UTC (rev 23381)
@@ -12,4 +12,8 @@
 	void redo();
 	
 	void undo();
+	
+	void dispose();
+	
+	String getCommandLabel();
 }

Added: branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/ISmooksCommandStackChangeListener.java
===================================================================
--- branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/ISmooksCommandStackChangeListener.java	                        (rev 0)
+++ branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/ISmooksCommandStackChangeListener.java	2010-07-13 07:32:12 UTC (rev 23381)
@@ -0,0 +1,14 @@
+/**
+ * 
+ */
+package org.jboss.tools.smooks.model.command;
+
+/**
+ * @author Dart
+ *
+ */
+public interface ISmooksCommandStackChangeListener {
+
+	void stackChanged(SmooksCommandStackEvent event);
+
+}


Property changes on: branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/ISmooksCommandStackChangeListener.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Modified: branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/RemoveCommand.java
===================================================================
--- branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/RemoveCommand.java	2010-07-13 06:46:00 UTC (rev 23380)
+++ branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/RemoveCommand.java	2010-07-13 07:32:12 UTC (rev 23381)
@@ -3,11 +3,15 @@
  */
 package org.jboss.tools.smooks.model.command;
 
+import java.util.Collection;
+
 /**
  * @author Dart
  *
  */
 public class RemoveCommand extends Command {
+	
+	private boolean removed=false;
 
 	public RemoveCommand() {
 		super();
@@ -19,4 +23,54 @@
 		// TODO Auto-generated constructor stub
 	}
 	
+	@Override
+	public void execute() {
+		if(!canExecute()) return;
+		try {
+			Object v = getPropertyValue();
+			if(!(v instanceof Collection)){
+				throw new RuntimeException("Value's type isn't Collection  , please check the " + "'" + propertyName + "'");
+			}
+			((Collection<?>)v).remove(value);
+			removed = true;
+		} catch (Exception e) {
+			e.printStackTrace();
+		} 
+	}
+	
+	
+	
+	@Override
+	public boolean canExecute() {
+		return (host != null && !removed && propertyName != null);
+	}
+
+	@Override
+	public boolean canRedo() {
+		return canExecute();
+	}
+
+	@Override
+	public boolean canUndo() {
+		return (host != null && removed && propertyName != null);
+	}
+
+	public void undo() {
+		if(!canUndo()) return;
+		try {
+			Object v = getPropertyValue();
+			if(!(v instanceof Collection)){
+				throw new RuntimeException("Value's type isn't Collection  , please check the " + "'" + propertyName + "'");
+			}
+			((Collection)v).add(value);
+			removed = false;
+		} catch (Exception e) {
+			e.printStackTrace();
+		} 
+	}
+
+	@Override
+	public String getCommandLabel() {
+		return "RemoveCommand";
+	}
 }

Modified: branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/SetCommand.java
===================================================================
--- branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/SetCommand.java	2010-07-13 06:46:00 UTC (rev 23380)
+++ branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/SetCommand.java	2010-07-13 07:32:12 UTC (rev 23381)
@@ -11,6 +11,8 @@
  */
 public class SetCommand extends Command {
 	
+	private boolean executed = false;
+	
 	public SetCommand() {
 		super();
 		// TODO Auto-generated constructor stub
@@ -30,6 +32,7 @@
 
 	@Override
 	public void execute() {
+		if(!canExecute()) return;
 		super.execute();
 		try {
 			Method setter = getSetterMethod();
@@ -37,14 +40,30 @@
 //			PropertyDescriptor pd = PropertyUtils.getPropertyDescriptor(host, propertyName);
 //			pd.getWriteMethod().invoke(host, value);
 			value = null;
-			execued = true;
+			executed = true;
 		} catch (Exception e) {
 			throw new RuntimeException(e);
 		} 
 	}
 
 	@Override
+	public boolean canExecute() {
+		return (host != null && !executed && propertyName != null);
+	}
+
+	@Override
+	public boolean canRedo() {
+		return super.canExecute();
+	}
+
+	@Override
+	public boolean canUndo() {
+		return (host != null && executed && propertyName != null);
+	}
+
+	@Override
 	public void undo() {
+		if(!canUndo()) return;
 		super.undo();
 		try {
 			Method setter = getSetterMethod();
@@ -52,8 +71,13 @@
 //			PropertyDescriptor pd = PropertyUtils.getPropertyDescriptor(host, propertyName);
 //			pd.setValue(propertyName, oldValue);
 			oldValue = null;
+			executed = false;
 		} catch (Exception e) {
 			e.printStackTrace();
 		} 
 	}
+	@Override
+	public String getCommandLabel() {
+		return "SetCommand";
+	}
 }

Modified: branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/SmooksCommandStack.java
===================================================================
--- branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/SmooksCommandStack.java	2010-07-13 06:46:00 UTC (rev 23380)
+++ branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/SmooksCommandStack.java	2010-07-13 07:32:12 UTC (rev 23381)
@@ -4,62 +4,331 @@
 package org.jboss.tools.smooks.model.command;
 
 import java.util.ArrayList;
+import java.util.EventObject;
 import java.util.List;
 import java.util.Properties;
+import java.util.Stack;
 
 /**
  * @author Dart
  *
  */
 public class SmooksCommandStack {
-	private List<ICommand> executedCommands = null;
+	/**
+	 * Constant indicating notification after a command has been executed (value
+	 * is 8).
+	 */
+	public static final int POST_EXECUTE = 8;
+	/**
+	 * Constant indicating notification after a command has been redone (value
+	 * is 16).
+	 */
+	public static final int POST_REDO = 16;
+	/**
+	 * Constant indicating notification after a command has been undone (value
+	 * is 32).
+	 */
+	public static final int POST_UNDO = 32;
+
+	/**
+	 * A bit-mask indicating notification after a command has done something.
+	 * Currently this includes after a command has been undone, redone, or
+	 * executed. This will include new events should they be introduced in the
+	 * future.
+	 * <P>
+	 * Usage<BR/>
+	 * 
+	 * <PRE>
+	 * if ((commandStackEvent.getDetail() &amp; CommandStack.POST_MASK) != 0) {
+	 * 	// Do something, like:
+	 * 	stopBatchingChanges();
+	 * }
+	 * </PRE>
+	 */
+	public static final int POST_MASK = new Integer(POST_EXECUTE | POST_UNDO
+			| POST_REDO).intValue();
+
+	/**
+	 * Constant indicating notification prior to executing a command (value is
+	 * 1).
+	 */
+	public static final int PRE_EXECUTE = 1;
+
+	/**
+	 * Constant indicating notification prior to redoing a command (value is 2).
+	 */
+	public static final int PRE_REDO = 2;
+
+	/**
+	 * Constant indicating notification prior to undoing a command (value is 4).
+	 */
+	public static final int PRE_UNDO = 4;
+
+	/**
+	 * A bit-mask indicating notification before a command makes a change.
+	 * Currently this includes before a command has been undone, redone, or
+	 * executed. This will include new events should they be introduced in the
+	 * future.
+	 * <P>
+	 * Usage<BR/>
+	 * 
+	 * <PRE>
+	 * if ((commandStackEvent.getDetail() &amp; CommandStack.PRE_MASK) != 0) {
+	 * 	// Do something, like:
+	 * 	startBatchingChanges();
+	 * }
+	 * </PRE>
+	 */
+	static final int PRE_MASK = new Integer(PRE_EXECUTE | PRE_UNDO | PRE_REDO)
+			.intValue();
+
+	private List<ISmooksCommandStackChangeListener> eventListeners = new ArrayList<ISmooksCommandStackChangeListener>();
+
+
+	private Stack<ICommand> redoable = new Stack<ICommand>();
+
+	private int saveLocation = 0;
+
+	private Stack<ICommand> undoable = new Stack<ICommand>();
+
+	private int undoLimit = 0;
+
+	/**
+	 * Constructs a new command stack. By default, there is no undo limit, and
+	 * isDirty() will return <code>false</code>.
+	 */
+	public SmooksCommandStack() {
+	}
+
+	/**
+	 * Appends the listener to the list of command stack listeners. Multiple
+	 * adds result in multiple notifications.
+	 * 
+	 * @since 3.1
+	 * @param listener
+	 *            the event listener
+	 */
+	public void addCommandStackEventListener(ISmooksCommandStackChangeListener listener) {
+		eventListeners.add(listener);
+	}
+
 	
-	private List<ICommand> undoedCommands = null;
-	
-	private ICommand currentExecuteCommand = null;
 
-	public List<ICommand> getExecutedCommands() {
-		
-		if(executedCommands == null){
-			executedCommands = new ArrayList<ICommand>();
+	/**
+	 * @return <code>true</code> if it is appropriate to call {@link #redo()}.
+	 */
+	public boolean canRedo() {
+		return !redoable.isEmpty();
+	}
+
+	/**
+	 * @return <code>true</code> if {@link #undo()} can be called
+	 */
+	public boolean canUndo() {
+		if (undoable.size() == 0)
+			return false;
+		return ((Command) undoable.lastElement()).canUndo();
+	}
+
+	/**
+	 * This will <code>dispose()</code> all the commands in both the undo and
+	 * redo stack. Both stacks will be empty afterwards.
+	 */
+	public void dispose() {
+		flushUndo();
+		flushRedo();
+	}
+
+	/**
+	 * Executes the specified Command if possible. Prior to executing the
+	 * command, a CommandStackEvent for {@link #PRE_EXECUTE} will be fired to
+	 * event listeners. Similarly, after attempting to execute the command, an
+	 * event for {@link #POST_EXECUTE} will be fired. If the execution of the
+	 * command completely normally, stack listeners will receive
+	 * {@link CommandStackListener#commandStackChanged(EventObject)
+	 * stackChanged} notification.
+	 * <P>
+	 * If the command is <code>null</code> or cannot be executed, nothing
+	 * happens.
+	 * 
+	 * @param command
+	 *            the Command to execute
+	 * @see CommandStackEventListener
+	 */
+	public void execute(ICommand command) {
+		if (command == null || !command.canExecute())
+			return;
+		flushRedo();
+		notifyListeners(command, PRE_EXECUTE);
+		try {
+			command.execute();
+			if (getUndoLimit() > 0) {
+				while (undoable.size() >= getUndoLimit()) {
+					((ICommand) undoable.remove(0)).dispose();
+					if (saveLocation > -1)
+						saveLocation--;
+				}
+			}
+			if (saveLocation > undoable.size())
+				saveLocation = -1; // The save point was somewhere in the redo
+									// stack
+			undoable.push(command);
+		} finally {
+			notifyListeners(command, POST_EXECUTE);
 		}
-		return executedCommands;
 	}
-	
-	
-	public List<ICommand> getUndoedCommands() {
-		if(undoedCommands == null){
-			undoedCommands = new ArrayList<ICommand>();
+
+	/**
+	 * Flushes the entire stack and resets the save location to zero. This
+	 * method might be called when performing "revert to saved".
+	 */
+	public void flush() {
+		flushRedo();
+		flushUndo();
+		saveLocation = 0;
+	}
+
+	private void flushRedo() {
+		while (!redoable.isEmpty())
+			((Command) redoable.pop()).dispose();
+	}
+
+	private void flushUndo() {
+		while (!undoable.isEmpty())
+			((Command) undoable.pop()).dispose();
+	}
+
+	/**
+	 * @return an array containing all commands in the order they were executed
+	 */
+	public Object[] getCommands() {
+		List<ICommand> commands = new ArrayList<ICommand>(undoable);
+		for (int i = redoable.size() - 1; i >= 0; i--) {
+			commands.add(redoable.get(i));
 		}
-		return undoedCommands;
+		return commands.toArray();
 	}
 
+	/**
+	 * Peeks at the top of the <i>redo</i> stack. This is useful for describing
+	 * to the User what will be redone. The returned <code>Command</code> has a
+	 * label describing it.
+	 * 
+	 * @return the top of the <i>redo</i> stack, which may be <code>null</code>
+	 */
+	public Command getRedoCommand() {
+		return redoable.isEmpty() ? null : (Command) redoable.peek();
+	}
 
-	public void execute(ICommand c){
-		c.execute();
-		addExecutedCommand(c);
+	/**
+	 * Peeks at the top of the <i>undo</i> stack. This is useful for describing
+	 * to the User what will be undone. The returned <code>Command</code> has a
+	 * label describing it.
+	 * 
+	 * @return the top of the <i>undo</i> stack, which may be <code>null</code>
+	 */
+	public Command getUndoCommand() {
+		return undoable.isEmpty() ? null : (Command) undoable.peek();
 	}
-	
-	public void undo(){
-		if(getExecutedCommands().size() > 0){
-			
+
+	/**
+	 * Returns the undo limit. The undo limit is the maximum number of atomic
+	 * operations that the User can undo. <code>-1</code> is used to indicate no
+	 * limit.
+	 * 
+	 * @return the undo limit
+	 */
+	public int getUndoLimit() {
+		return undoLimit;
+	}
+
+	/**
+	 * Returns true if the stack is dirty. The stack is dirty whenever the last
+	 * executed or redone command is different than the command that was at the
+	 * top of the undo stack when {@link #markSaveLocation()} was last called.
+	 * 
+	 * @return <code>true</code> if the stack is dirty
+	 */
+	public boolean isDirty() {
+		return undoable.size() != saveLocation;
+	}
+
+
+	/**
+	 * Notifies command stack event listeners that the command stack has changed
+	 * to the specified state.
+	 * 
+	 * @param command
+	 *            the command
+	 * @param state
+	 *            the current stack state
+	 * @since 3.2
+	 */
+	protected void notifyListeners(ICommand command, int state) {
+		SmooksCommandStackEvent event = new SmooksCommandStackEvent(this, command, state);
+		for (int i = 0; i < eventListeners.size(); i++)
+			((ISmooksCommandStackChangeListener) eventListeners.get(i))
+					.stackChanged(event);
+	}
+
+	/**
+	 * Calls redo on the Command at the top of the <i>redo</i> stack, and pushes
+	 * that Command onto the <i>undo</i> stack. This method should only be
+	 * called when {@link #canUndo()} returns <code>true</code>.
+	 */
+	public void redo() {
+		// Assert.isTrue(canRedo())
+		if (!canRedo())
+			return;
+		Command command = (Command) redoable.pop();
+		notifyListeners(command, PRE_REDO);
+		try {
+			command.redo();
+			undoable.push(command);
+		} finally {
+			notifyListeners(command, POST_REDO);
 		}
 	}
-	
-	public void addExecutedCommand(ICommand c){
-		getExecutedCommands().add(c);
+
+	/**
+	 * Removes the first occurrence of the specified listener.
+	 * 
+	 * @param listener
+	 *            the listener
+	 */
+	public void removeCommandStackEventListener(
+			ISmooksCommandStackChangeListener listener) {
+		eventListeners.remove(listener);
 	}
+
 	
-	public void removeCommand(ICommand c){
-		getExecutedCommands().remove(c);
+
+	/**
+	 * Sets the undo limit. The undo limit is the maximum number of atomic
+	 * operations that the User can undo. <code>-1</code> is used to indicate no
+	 * limit.
+	 * 
+	 * @param undoLimit
+	 *            the undo limit
+	 */
+	public void setUndoLimit(int undoLimit) {
+		this.undoLimit = undoLimit;
 	}
-	
-//	public boolean isDirty(){
-//		
-//	}
-	
-	public void cleanStack(){
-		getExecutedCommands().clear();
-		currentExecuteCommand = null;
+
+	/**
+	 * Undoes the most recently executed (or redone) Command. The Command is
+	 * popped from the undo stack to and pushed onto the redo stack. This method
+	 * should only be called when {@link #canUndo()} returns <code>true</code>.
+	 */
+	public void undo() {
+		// Assert.isTrue(canUndo());
+		Command command = (Command) undoable.pop();
+		notifyListeners(command, PRE_UNDO);
+		try {
+			command.undo();
+			redoable.push(command);
+		} finally {
+			notifyListeners(command, POST_UNDO);
+		}
 	}
 }

Added: branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/SmooksCommandStackEvent.java
===================================================================
--- branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/SmooksCommandStackEvent.java	                        (rev 0)
+++ branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/SmooksCommandStackEvent.java	2010-07-13 07:32:12 UTC (rev 23381)
@@ -0,0 +1,58 @@
+package org.jboss.tools.smooks.model.command;
+
+import java.util.EventObject;
+
+public class SmooksCommandStackEvent extends EventObject {
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -2132661251732718650L;
+	
+	private final ICommand command;
+	private final int detail;
+
+	public SmooksCommandStackEvent(SmooksCommandStack smooksCommandStack,
+			ICommand command, int state) {
+		super(smooksCommandStack);
+		this.command = command;
+		this.detail = state;
+	}
+
+	
+	public ICommand getCommand() {
+		return command;
+	}
+
+	/**
+	 * Returns <code>true</code> if this event is fired prior to the stack
+	 * changing.
+	 * 
+	 * @return <code>true</code> if pre-change event
+	 * @since 3.2
+	 */
+	public final boolean isPreChangeEvent() {
+		return 0 != (getDetail() & SmooksCommandStack.PRE_MASK);
+	}
+
+	/**
+	 * Returns <code>true</code> if this event is fired after the stack having
+	 * changed.
+	 * 
+	 * @return <code>true</code> if post-change event
+	 * @since 3.2
+	 */
+	public final boolean isPostChangeEvent() {
+		return 0 != (getDetail() & SmooksCommandStack.POST_MASK);
+	}
+
+	/**
+	 * Returns an integer identifying the type of event which has occurred.
+	 * 
+	 * @since 3.1
+	 * @return the detail of the event
+	 */
+	public int getDetail() {
+		return detail;
+	}
+
+}


Property changes on: branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/SmooksCommandStackEvent.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/UnSetCommand.java
===================================================================
--- branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/UnSetCommand.java	                        (rev 0)
+++ branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/UnSetCommand.java	2010-07-13 07:32:12 UTC (rev 23381)
@@ -0,0 +1,83 @@
+/**
+ * 
+ */
+package org.jboss.tools.smooks.model.command;
+
+import java.lang.reflect.Method;
+
+/**
+ * @author Dart
+ *
+ */
+public class UnSetCommand extends Command {
+	
+	private boolean executed = false;
+
+	public UnSetCommand() {
+		super();
+		// TODO Auto-generated constructor stub
+	}
+
+	public UnSetCommand(Object host, String propertyName) {
+		super(host, null, propertyName);
+		// TODO Auto-generated constructor stub
+	}
+	
+	public void execute(Object host , Object value , String propertyName){
+		this.host = host;
+		this.value = value;
+		this.propertyName = propertyName;
+		execute();
+	}
+	
+	@Override
+	public boolean canExecute() {
+		return (host != null && !executed && propertyName != null);
+	}
+
+	@Override
+	public boolean canRedo() {
+		return super.canExecute();
+	}
+
+	@Override
+	public boolean canUndo() {
+		return (host != null && executed && propertyName != null);
+	}
+	
+	@Override
+	public void execute() {
+		if(!canExecute()) return;
+		super.execute();
+		try {
+			Method setter = getSetterMethod();
+			setter.invoke(host, new Object[]{null});
+//			PropertyDescriptor pd = PropertyUtils.getPropertyDescriptor(host, propertyName);
+//			pd.getWriteMethod().invoke(host, value);
+			executed = true;
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		} 
+	}
+	
+	@Override
+	public String getCommandLabel() {
+		return "UnSetCommand";
+	}
+
+	@Override
+	public void undo() {
+		if(!canUndo()) return;
+		super.undo();
+		try {
+			Method setter = getSetterMethod();
+			setter.invoke(host, oldValue);
+//			PropertyDescriptor pd = PropertyUtils.getPropertyDescriptor(host, propertyName);
+//			pd.setValue(propertyName, oldValue);
+			executed = false;
+		} catch (Exception e) {
+			e.printStackTrace();
+		} 
+	}
+
+}


Property changes on: branches/smooks-dmb/plugins/org.jboss.tools.smooks.model/src/org/jboss/tools/smooks/model/command/UnSetCommand.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Copied: branches/smooks-dmb/tests/org.jboss.tools.smooks.model.test/src/org/jboss/tools/smooks/model/command/CommandTest.java (from rev 23369, branches/smooks-dmb/tests/org.jboss.tools.smooks.model.test/src/org/jboss/tools/smooks/model/command/SetCommandTest.java)
===================================================================
--- branches/smooks-dmb/tests/org.jboss.tools.smooks.model.test/src/org/jboss/tools/smooks/model/command/CommandTest.java	                        (rev 0)
+++ branches/smooks-dmb/tests/org.jboss.tools.smooks.model.test/src/org/jboss/tools/smooks/model/command/CommandTest.java	2010-07-13 07:32:12 UTC (rev 23381)
@@ -0,0 +1,213 @@
+/**
+ * 
+ */
+package org.jboss.tools.smooks.model.command;
+
+import junit.framework.TestCase;
+
+import org.jboss.tools.smooks.model.csv.CSVReader;
+import org.jboss.tools.smooks.model.javabean.Bean;
+import org.jboss.tools.smooks.model.javabean.Wiring;
+import org.junit.Assert;
+
+/**
+ * @author Dart
+ * 
+ */
+public class CommandTest extends TestCase {
+	public void testSetCommand() {
+		CSVReader reader = new CSVReader();
+		
+		SetCommand command1 = new SetCommand(reader, "name,address,age", "fields");
+		SetCommand command2 = new SetCommand(reader, "people", "rootElementName");
+		SetCommand command3 = new SetCommand(reader, "person", "recordElementName");
+		SetCommand command4 = new SetCommand(reader, true, "indent");
+		
+		
+		command1.execute();
+		command2.execute();
+		command3.execute();
+		command4.execute();
+		
+		Assert.assertSame(reader.getFields(), "name,address,age");
+		Assert.assertSame(reader.getRecordElementName(), "person");
+		Assert.assertSame(reader.getRootElementName(), "people");
+		Assert.assertSame(reader.getIndent(),true);
+		
+		
+		
+		command1.undo();
+		command2.undo();
+		command3.undo();
+		command4.undo();
+		
+		Assert.assertSame(reader.getFields(), null);
+		Assert.assertSame(reader.getRecordElementName(), null);
+		Assert.assertSame(reader.getRootElementName(),null);
+//		Assert.assertSame(reader.getIndent(),true);
+		
+		command1.redo();
+		command2.redo();
+		command3.redo();
+		command4.redo();
+		
+		Assert.assertSame(reader.getFields(), "name,address,age");
+		Assert.assertSame(reader.getRecordElementName(), "person");
+		Assert.assertSame(reader.getRootElementName(), "people");
+		Assert.assertSame(reader.getIndent(),true);
+		
+//		reader.setFields("name,address,age");
+//		reader.setRootElementName("people");
+//		reader.setRecordElementName("person");
+//		reader.setIndent(true);
+		
+	}
+	
+	public void testAddCommand(){
+		Bean people = new Bean();
+		Wiring w = new Wiring();
+		
+		Assert.assertTrue(people.getWireBindings().isEmpty());
+		
+		AddCommand c = new AddCommand(people, w, "wireBindings");
+		
+		c.execute();
+		
+		Assert.assertTrue(people.getWireBindings().get(0) == w);
+		
+		c.undo();
+		
+		Assert.assertTrue(people.getWireBindings().isEmpty());
+		
+		c.redo();
+		
+		Assert.assertTrue(people.getWireBindings().get(0) == w);
+	}
+	
+	public void testRemoveCommand(){
+		Bean people = new Bean();
+		Wiring w = new Wiring();
+		AddCommand c = new AddCommand(people, w, "wireBindings");
+		c.execute();
+		
+		Assert.assertTrue(people.getWireBindings().get(0) == w);
+		RemoveCommand rc = new RemoveCommand(people, w, "wireBindings");
+		rc.execute();
+		Assert.assertTrue(people.getWireBindings().isEmpty());
+		
+		rc.undo();
+		Assert.assertTrue(people.getWireBindings().get(0) == w);
+		
+		rc.redo();
+		Assert.assertTrue(people.getWireBindings().isEmpty());
+	}
+	
+	public void testUnSetCommand(){
+		Bean people = new Bean();
+		SetCommand c1 = new SetCommand(people, "people", "beanId");
+		SetCommand c2 = new SetCommand(people, "java.util.ArrayList", "beanClass");
+		
+		CompositeCommand cc = new CompositeCommand();
+		cc.appendCommand(c1);
+		cc.appendCommand(c2);
+		cc.execute();
+		Assert.assertTrue(people.getBeanId().equals("people"));
+		Assert.assertTrue(people.getBeanClass().equals("java.util.ArrayList"));
+		
+		UnSetCommand us = new UnSetCommand(people, "beanId");
+		UnSetCommand us1 = new UnSetCommand(people, "beanClass");
+		
+		us.execute();
+		us1.execute();
+		Assert.assertTrue(people.getBeanId() == null);
+		Assert.assertTrue(people.getBeanClass() == null);
+		
+		us.undo();
+		us1.undo();
+		Assert.assertTrue(people.getBeanId().equals("people"));
+		Assert.assertTrue(people.getBeanClass().equals("java.util.ArrayList"));
+		
+		us.redo();
+		us1.redo();
+		Assert.assertTrue(people.getBeanId() == null);
+		Assert.assertTrue(people.getBeanClass() == null);
+	}
+	
+	public void testCompositeCommand(){
+		Bean people = new Bean();
+		Wiring w = new Wiring();
+		AddCommand c = new AddCommand(people, w, "wireBindings");
+		SetCommand c1 = new SetCommand(people, "people", "beanId");
+		SetCommand c2 = new SetCommand(people, "java.util.ArrayList", "beanClass");
+		
+		CompositeCommand cc = new CompositeCommand();
+		cc.appendCommand(c);
+		cc.appendCommand(c1);
+		cc.appendCommand(c2);
+		
+		cc.execute();
+		Assert.assertTrue(people.getWireBindings().get(0) == w);
+		Assert.assertTrue(people.getBeanId().equals("people"));
+		Assert.assertTrue(people.getBeanClass().equals("java.util.ArrayList"));
+		
+		cc.undo();
+		Assert.assertTrue(people.getWireBindings().isEmpty());
+		Assert.assertTrue(people.getBeanId() == null);
+		Assert.assertTrue(people.getBeanClass() == null);
+		
+		cc.redo();
+		Assert.assertTrue(people.getWireBindings().get(0) == w);
+		Assert.assertTrue(people.getBeanId().equals("people"));
+		Assert.assertTrue(people.getBeanClass().equals("java.util.ArrayList"));
+	}
+	
+	public void testCommandStatck(){
+		SmooksCommandStack stack = new SmooksCommandStack();
+		ISmooksCommandStackChangeListener listener = new ISmooksCommandStackChangeListener() {
+			
+			public void stackChanged(SmooksCommandStackEvent event) {
+				if(event.getDetail() == SmooksCommandStack.PRE_EXECUTE){
+					System.out.println("pre execute " + event.getCommand().getCommandLabel());
+				}
+				if(event.getDetail() == SmooksCommandStack.POST_EXECUTE){
+					System.out.println("post execute " + event.getCommand().getCommandLabel());
+				}
+				if(event.getDetail() == SmooksCommandStack.PRE_REDO){
+					System.out.println("pre redo " + event.getCommand().getCommandLabel());
+				}
+				if(event.getDetail() == SmooksCommandStack.POST_REDO){
+					System.out.println("post redo " + event.getCommand().getCommandLabel());
+				}
+				if(event.getDetail() == SmooksCommandStack.PRE_UNDO){
+					System.out.println("pre undo " + event.getCommand().getCommandLabel());
+				}
+				if(event.getDetail() == SmooksCommandStack.POST_UNDO){
+					System.out.println("post undo " + event.getCommand().getCommandLabel());
+				}
+			}
+		};
+		
+		stack.addCommandStackEventListener(listener);
+		
+		Bean people = new Bean();
+		Wiring w = new Wiring();
+		
+		Assert.assertTrue(people.getWireBindings().isEmpty());
+		
+		SetCommand c1 = new SetCommand(people, "people", "beanId");
+		AddCommand c = new AddCommand(people, w, "wireBindings");
+		
+		
+		Assert.assertTrue(!stack.canRedo()&&!stack.canUndo());
+		stack.execute(c);
+		
+		
+		Assert.assertTrue(people.getWireBindings().get(0) == w);
+		Assert.assertTrue(!stack.canRedo());
+		stack.undo();
+		stack.execute(c1);
+		stack.undo();
+		Assert.assertTrue(people.getBeanId()==null);
+		
+	}
+}


Property changes on: branches/smooks-dmb/tests/org.jboss.tools.smooks.model.test/src/org/jboss/tools/smooks/model/command/CommandTest.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Deleted: branches/smooks-dmb/tests/org.jboss.tools.smooks.model.test/src/org/jboss/tools/smooks/model/command/SetCommandTest.java
===================================================================
--- branches/smooks-dmb/tests/org.jboss.tools.smooks.model.test/src/org/jboss/tools/smooks/model/command/SetCommandTest.java	2010-07-13 06:46:00 UTC (rev 23380)
+++ branches/smooks-dmb/tests/org.jboss.tools.smooks.model.test/src/org/jboss/tools/smooks/model/command/SetCommandTest.java	2010-07-13 07:32:12 UTC (rev 23381)
@@ -1,63 +0,0 @@
-/**
- * 
- */
-package org.jboss.tools.smooks.model.command;
-
-import junit.framework.TestCase;
-
-import org.jboss.tools.smooks.model.csv.CSVReader;
-import org.junit.Assert;
-
-/**
- * @author Dart
- * 
- */
-public class SetCommandTest extends TestCase {
-	public void testCSVReaderSet() {
-		CSVReader reader = new CSVReader();
-		
-		SetCommand command1 = new SetCommand(reader, "name,address,age", "fields");
-		SetCommand command2 = new SetCommand(reader, "people", "rootElementName");
-		SetCommand command3 = new SetCommand(reader, "person", "recordElementName");
-		SetCommand command4 = new SetCommand(reader, true, "indent");
-		
-		
-		command1.execute();
-		command2.execute();
-		command3.execute();
-		command4.execute();
-		
-		Assert.assertSame(reader.getFields(), "name,address,age");
-		Assert.assertSame(reader.getRecordElementName(), "person");
-		Assert.assertSame(reader.getRootElementName(), "people");
-		Assert.assertSame(reader.getIndent(),true);
-		
-		
-		
-		command1.undo();
-		command2.undo();
-		command3.undo();
-		command4.undo();
-		
-		Assert.assertSame(reader.getFields(), null);
-		Assert.assertSame(reader.getRecordElementName(), null);
-		Assert.assertSame(reader.getRootElementName(),null);
-//		Assert.assertSame(reader.getIndent(),true);
-		
-		command1.redo();
-		command2.redo();
-		command3.redo();
-		command4.redo();
-		
-		Assert.assertSame(reader.getFields(), "name,address,age");
-		Assert.assertSame(reader.getRecordElementName(), "person");
-		Assert.assertSame(reader.getRootElementName(), "people");
-		Assert.assertSame(reader.getIndent(),true);
-		
-//		reader.setFields("name,address,age");
-//		reader.setRootElementName("people");
-//		reader.setRecordElementName("person");
-//		reader.setIndent(true);
-		
-	}
-}



More information about the jbosstools-commits mailing list