57b5dc1efe690532e373d7663cfd6bcb4b5dcff9
[openflowjava.git] / third-party / openflowj_netty / src / main / java / org / openflow / protocol / action / OFAction.java
1 /**
2 *    Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior
3 *    University
4
5 *    Licensed under the Apache License, Version 2.0 (the "License"); you may
6 *    not use this file except in compliance with the License. You may obtain
7 *    a copy of the License at
8 *
9 *         http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *    Unless required by applicable law or agreed to in writing, software
12 *    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 *    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 *    License for the specific language governing permissions and limitations
15 *    under the License.
16 **/
17
18 package org.openflow.protocol.action;
19
20
21 import org.jboss.netty.buffer.ChannelBuffer;
22 import org.openflow.util.U16;
23
24 /**
25  * The base class for all OpenFlow Actions.
26  *
27  * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 11, 2010
28  */
29 public class OFAction implements Cloneable {
30     /**
31      * Note the true minimum length for this header is 8 including a pad to 64
32      * bit alignment, however as this base class is used for demuxing an
33      * incoming Action, it is only necessary to read the first 4 bytes.  All
34      * Actions extending this class are responsible for reading/writing the
35      * first 8 bytes, including the pad if necessary.
36      */
37     public static int MINIMUM_LENGTH = 4;
38     public static int OFFSET_LENGTH = 2;
39     public static int OFFSET_TYPE = 0;
40
41     protected OFActionType type;
42     protected short length;
43
44     /**
45      * Get the length of this message
46      *
47      * @return
48      */
49     public short getLength() {
50         return length;
51     }
52
53     /**
54      * Get the length of this message, unsigned
55      *
56      * @return
57      */
58     public int getLengthU() {
59         return U16.f(length);
60     }
61
62     /**
63      * Set the length of this message
64      *
65      * @param length
66      */
67     public OFAction setLength(short length) {
68         this.length = length;
69         return this;
70     }
71
72     /**
73      * Get the type of this message
74      *
75      * @return OFActionType enum
76      */
77     public OFActionType getType() {
78         return this.type;
79     }
80
81     /**
82      * Set the type of this message
83      *
84      * @param type
85      */
86     public void setType(OFActionType type) {
87         this.type = type;
88     }
89
90     /**
91      * Returns a summary of the message
92      * @return "ofmsg=v=$version;t=$type:l=$len:xid=$xid"
93      */
94     public String toString() {
95         return "ofaction" +
96             ";t=" + this.getType() +
97             ";l=" + this.getLength();
98     }
99     
100     /**
101      * Given the output from toString(), 
102      * create a new OFAction
103      * @param val
104      * @return
105      */
106     public static OFAction fromString(String val) {
107         String tokens[] = val.split(";");
108         if (!tokens[0].equals("ofaction"))
109             throw new IllegalArgumentException("expected 'ofaction' but got '" + 
110                     tokens[0] + "'");
111         String type_tokens[] = tokens[1].split("="); 
112         String len_tokens[] = tokens[2].split("=");
113         OFAction action = new OFAction();
114         action.setLength(Short.valueOf(len_tokens[1]));
115         action.setType(OFActionType.valueOf(type_tokens[1]));
116         return action;
117     }
118
119     public void readFrom(ChannelBuffer data) {
120         this.type = OFActionType.valueOf(data.readShort());
121         this.length = data.readShort();
122         // Note missing PAD, see MINIMUM_LENGTH comment for details
123     }
124
125     public void writeTo(ChannelBuffer data) {
126         data.writeShort(type.getTypeValue());
127         data.writeShort(length);
128         // Note missing PAD, see MINIMUM_LENGTH comment for details
129     }
130
131     @Override
132     public int hashCode() {
133         final int prime = 347;
134         int result = 1;
135         result = prime * result + length;
136         result = prime * result + ((type == null) ? 0 : type.hashCode());
137         return result;
138     }
139
140     @Override
141     public boolean equals(Object obj) {
142         if (this == obj) {
143             return true;
144         }
145         if (obj == null) {
146             return false;
147         }
148         if (!(obj instanceof OFAction)) {
149             return false;
150         }
151         OFAction other = (OFAction) obj;
152         if (length != other.length) {
153             return false;
154         }
155         if (type == null) {
156             if (other.type != null) {
157                 return false;
158             }
159         } else if (!type.equals(other.type)) {
160             return false;
161         }
162         return true;
163     }
164
165     /* (non-Javadoc)
166      * @see java.lang.Object#clone()
167      */
168     @Override
169     public OFAction clone() throws CloneNotSupportedException {
170         return (OFAction) super.clone();
171     }
172     
173 }