Renamed devicemanager, flowprogrammer, linkdiscovery and util packages

net.onrc.onos.ofcontroller.devicemanager.* => net.onrc.onos.core.devicemanager.*
net.onrc.onos.ofcontroller.flowprogrammer.* => net.onrc.onos.core.flowprogrammer.*
net.onrc.onos.ofcontroller.linkdiscovery.* => net.onrc.onos.core.linkdiscovery.*
net.onrc.onos.ofcontroller.util.* => net.onrc.onos.core.util.*

Change-Id: Iaa865af552e8fb3a589e73d006569ac79f5a0f08
diff --git a/src/main/java/net/onrc/onos/core/util/FlowEntryActions.java b/src/main/java/net/onrc/onos/core/util/FlowEntryActions.java
new file mode 100644
index 0000000..8839ceb
--- /dev/null
+++ b/src/main/java/net/onrc/onos/core/util/FlowEntryActions.java
@@ -0,0 +1,148 @@
+package net.onrc.onos.core.util;
+
+import java.util.ArrayList;
+
+import org.codehaus.jackson.annotate.JsonIgnore;
+import org.codehaus.jackson.annotate.JsonProperty;
+
+/**
+ * The class representing multiple Flow Entry actions.
+ *
+ * A set of Flow Entry actions need to be applied to each packet.
+ */
+public class FlowEntryActions {
+    private ArrayList<FlowEntryAction> actions;	// The Flow Entry Actions
+
+    /**
+     * Default constructor.
+     */
+    public FlowEntryActions() {
+	actions = new ArrayList<FlowEntryAction>();
+    }
+
+    /**
+     * Constructor from a string.
+     *
+     * The string has the following form:
+     *  [[type=XXX action=XXX];[type=XXX action=XXX];...;]
+     *
+     * @param actionsStr the set of actions as a string.
+     */
+    public FlowEntryActions(String actionsStr) {
+	this.fromString(actionsStr);
+    }
+
+    /**
+     * Copy constructor.
+     *
+     * @param other the object to copy from.
+     */
+    public FlowEntryActions(FlowEntryActions other) {
+	actions = new ArrayList<FlowEntryAction>();
+
+	for (FlowEntryAction action : other.actions) {
+	    FlowEntryAction newAction = new FlowEntryAction(action);
+	    actions.add(newAction);
+	}
+    }
+
+    /**
+     * Get the Flow Entry Actions.
+     *
+     * @return the Flow Entry Actions.
+     */
+    @JsonProperty("actions")
+    public ArrayList<FlowEntryAction> actions() {
+	return actions;
+    }
+
+    /**
+     * Set the Flow Entry Actions.
+     *
+     * @param actions the Flow Entry Actions to set.
+     */
+    @JsonProperty("actions")
+    public void setActions(ArrayList<FlowEntryAction> actions) {
+	this.actions = actions;
+    }
+
+    /**
+     * Add a Flow Entry Action.
+     *
+     * @param flowEntryAction the Flow Entry Action to add.
+     */
+    public void addAction(FlowEntryAction flowEntryAction) {
+	actions.add(flowEntryAction);
+    }
+
+    /**
+     * Test whether the set of actions is empty.
+     *
+     * @return true if the set of actions is empty, otherwise false.
+     */
+    @JsonIgnore
+    public Boolean isEmpty() {
+	return actions.isEmpty();
+    }
+
+    /**
+     * Convert the set of actions to a string.
+     *
+     * The string has the following form:
+     *  [[type=XXX action=XXX];[type=XXX action=XXX];...;]
+     *
+     * @return the set of actions as a string.
+     */
+    @Override
+    public String toString() {
+	String ret = "[";
+	for (FlowEntryAction action : actions) {
+	    ret += action.toString() + ";";
+	}
+	ret += "]";
+
+	return ret;
+    }
+
+    /**
+     * Convert a string to a set of actions.
+     *
+     * The string has the following form:
+     *  [[type=XXX action=XXX];[type=XXX action=XXX];...;]
+     *
+     * @param actionsStr the set of actions as a string.
+     */
+    public void fromString(String actionsStr) {
+	String decode = actionsStr;
+
+	actions = new ArrayList<FlowEntryAction>();
+
+	if (decode.isEmpty())
+	    return;		// Nothing to do
+
+	// Remove the '[' and ']' in the beginning and the end of the string
+	if ((decode.length() > 1) && (decode.charAt(0) == '[') &&
+	    (decode.charAt(decode.length() - 1) == ']')) {
+	    decode = decode.substring(1, decode.length() - 1);
+	} else {
+	    throw new IllegalArgumentException("Invalid action string");
+	}
+
+	// Split the string, and decode each action
+	String[] parts = decode.split(";");
+	for (int i = 0; i < parts.length; i++) {
+	    decode = parts[i];
+	    if ((decode == null) || decode.isEmpty())
+		continue;
+	    FlowEntryAction flowEntryAction = null;
+	    try {
+		flowEntryAction = new FlowEntryAction(decode);
+	    } catch (IllegalArgumentException e) {
+		// TODO: Ignore invalid actions for now
+		continue;
+	    }
+	    if (flowEntryAction != null)
+		actions.add(flowEntryAction);
+	}
+    }
+}