981b175e197242a0e4347b3407ad3cfc86cb3576
[controller.git] / opendaylight / adsal / sal / api / src / main / java / org / opendaylight / controller / sal / action / Action.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.sal.action;
10
11 import java.util.ArrayList;
12 import java.util.Collection;
13 import java.util.Collections;
14 import java.util.List;
15 import java.util.concurrent.ConcurrentMap;
16 import java.util.concurrent.ConcurrentHashMap;
17
18 import org.opendaylight.controller.sal.core.Property;
19
20 import javax.xml.bind.annotation.XmlAccessType;
21 import javax.xml.bind.annotation.XmlAccessorType;
22 import javax.xml.bind.annotation.XmlElement;
23 import javax.xml.bind.annotation.XmlRootElement;
24 import java.io.Serializable;
25
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29
30 /**
31  * Represents the generic action to be applied to the matched
32  * frame/packet/message
33  */
34 @XmlRootElement
35 @XmlAccessorType(XmlAccessType.NONE)
36 public abstract class Action implements Serializable {
37     private static final long serialVersionUID = 1L;
38     private static final Logger logger = LoggerFactory.getLogger(Action.class);
39     private static boolean debug = false; // Enable to find where in the code an
40     // invalid assignment is made
41     @XmlElement
42     protected ActionType type;
43     private transient boolean isValid = true;
44     private ConcurrentMap<String, Property> props;
45
46     /* Dummy constructor for JAXB */
47     public Action() {
48     }
49
50     /**
51      * Checks if the passed value is in the valid range for this action
52      *
53      * @param value
54      * @return boolean
55      */
56     protected void checkValue(int value) {
57         if (type.isValidTarget(value) == false) {
58             isValid = false;
59             throwValueException(value);
60         }
61     }
62
63     /**
64      * Checks if the passed value is in the valid range for the passed action
65      * type This method is used for complex Action types which are
66      *
67      * @param value
68      * @return boolean
69      */
70     protected void checkValue(ActionType type, int value) {
71         if (type.isValidTarget(value) == false) {
72             isValid = false;
73             throwValueException(value);
74         }
75     }
76
77     /**
78      * Throw and handle the invalid value exception
79      *
80      * @param value
81      * @return void
82      */
83     private void throwValueException(int value) {
84         String error = "Invalid field value assignement. For type: " + type.getId() + " Expected: " + type.getRange()
85                 + ", Got: 0x" + Integer.toHexString(value);
86         try {
87             throw new Exception(error);
88         } catch (Exception e) {
89             logger.error(e.getMessage());
90             if (debug) {
91                 logger.error("", e);
92             }
93         }
94     }
95
96     /**
97      * Gets the list of metadata currently registered with this match
98      *
99      * @return List of metadata currently registered
100      */
101     public List <Property> getMetadatas() {
102         if (this.props != null) {
103             // Return all the values in the map
104             Collection res = this.props.values();
105             if (res == null) {
106                 return Collections.emptyList();
107             }
108             return new ArrayList<Property>(res);
109         }
110         return Collections.emptyList();
111     }
112
113     /**
114      * Gets the metadata registered with a name if present
115      *
116      * @param name the name of the property to be extracted
117      *
118      * @return List of metadata currently registered
119      */
120     public Property getMetadata(String name) {
121         if (name == null) {
122             return null;
123         }
124         if (this.props != null) {
125             // Return the Property associated to the name
126             return this.props.get(name);
127         }
128         return null;
129     }
130
131     /**
132      * Sets the metadata associated to a name. If the name or prop is NULL,
133      * an exception NullPointerException will be raised.
134      *
135      * @param name the name of the property to be set
136      * @param prop, property to be set
137      */
138     public void setMetadata(String name, Property prop) {
139         if (this.props == null) {
140             props = new ConcurrentHashMap<String, Property>();
141         }
142
143         if (this.props != null) {
144             this.props.put(name, prop);
145         }
146     }
147
148     /**
149      * Remove the metadata associated to a name. If the name is NULL,
150      * nothing will be removed.
151      *
152      * @param name the name of the property to be set
153      * @param prop, property to be set
154      *
155      * @return List of metadata currently registered
156      */
157     public void removeMetadata(String name) {
158         if (this.props == null) {
159             return;
160         }
161
162         if (this.props != null) {
163             this.props.remove(name);
164         }
165         // It's intentional to keep the this.props still allocated
166         // till the parent data structure will be alive, so to avoid
167         // unnecessary allocation/deallocation, even if it's holding
168         // nothing
169     }
170
171     /**
172      * Returns the type of this action
173      *
174      * @return ActionType
175      */
176     public ActionType getType() {
177         return type;
178     }
179
180     /**
181      * Returns the id of this action
182      *
183      * @return String
184      */
185     public String getId() {
186         return type.getId();
187     }
188
189     /**
190      * Returns whether the Action is valid or not
191      *
192      * @return boolean
193      */
194     public boolean isValid() {
195         return isValid;
196     }
197
198     @Override
199     public int hashCode() {
200         final int prime = 31;
201         int result = 1;
202         result = prime * result + ((type == null) ? 0 : type.calculateConsistentHashCode());
203         return result;
204     }
205
206     @Override
207     public boolean equals(Object obj) {
208         if (this == obj) {
209             return true;
210         }
211         if (obj == null) {
212             return false;
213         }
214         if (getClass() != obj.getClass()) {
215             return false;
216         }
217         Action other = (Action) obj;
218         if (type != other.type) {
219             return false;
220         }
221         return true;
222     }
223
224     @Override
225     public String toString() {
226         return type.toString();
227     }
228
229 }