ISSUE
[controller.git] / opendaylight / sal / api / src / main / java / org / opendaylight / controller / sal / match / MatchField.java
1
2 /*
3  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
4  *
5  * This program and the accompanying materials are made available under the
6  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7  * and is available at http://www.eclipse.org/legal/epl-v10.html
8  */
9
10 package org.opendaylight.controller.sal.match;
11
12 import java.io.Serializable;
13
14 import javax.xml.bind.annotation.XmlAccessType;
15 import javax.xml.bind.annotation.XmlAccessorType;
16 import javax.xml.bind.annotation.XmlElement;
17 import javax.xml.bind.annotation.XmlRootElement;
18
19 import org.apache.commons.lang3.builder.EqualsBuilder;
20 import org.apache.commons.lang3.builder.HashCodeBuilder;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23
24 /**
25  * Represents the generic matching field
26  *
27  */
28
29 @XmlRootElement
30 @XmlAccessorType(XmlAccessType.NONE)
31
32 public class MatchField implements Cloneable, Serializable {
33         private static final long serialVersionUID = 1L;
34         private static final Logger logger = LoggerFactory
35             .getLogger(MatchField.class);
36         private MatchType type; // the field we want to match
37     private Object value; // the value of the field we want to match
38     private Object mask; // the value of the mask we want to match on the specified field
39     private transient boolean isValid;
40
41     // To satisfy JAXB
42     private MatchField() {
43     }
44     /**
45      * Mask based match constructor
46      *
47      * @param type
48      * @param value
49      * @param mask   has to be of the same class type of value. A null mask means full match
50      */
51     public MatchField(MatchType type, Object value, Object mask) {
52         this.type = type;
53         this.value = value;
54         this.mask = mask;
55         this.isValid = checkValueType() && checkValues(); // Keep this logic, value checked only if type check is fine
56     }
57
58     /**
59      * Full match constructor
60      *
61      * @param type
62      * @param value
63      */
64     public MatchField(MatchType type, Object value) {
65         this.type = type;
66         this.value = value;
67         this.mask = null;
68         this.isValid = checkValueType() && checkValues(); // Keep this logic, value checked only if type check is fine
69     }
70
71     /**
72      * Returns the value set for this match field
73      *
74      * @return
75      */
76     public Object getValue() {
77         return value;
78     }
79     
80     @XmlElement(name="value")
81     private String getValueString() {
82         return type.stringify(value);
83     }
84
85     /**
86      * Returns the type field this match field object is for
87      *
88      * @return
89      */
90     public MatchType getType() {
91         return type;
92     }
93
94     @XmlElement(name="type")
95     private String getTypeString() {
96         return type.toString();
97     }
98
99     /**
100      * Returns the mask value set for this field match
101      * A null mask means this is a full match
102      * @return
103      */
104     public Object getMask() {
105         return mask;
106     }
107     
108     @XmlElement(name="mask")
109     private String getMaskString() {
110         return type.stringify(mask); 
111     }
112
113     /**
114      * Returns the bitmask set for this field match
115      *
116      * @return
117      */
118     public long getBitMask() {
119         return type.getBitMask(mask);
120     }
121
122     /**
123      * Returns whether the field match configuration is valid or not
124      *
125      * @return
126      */
127     public boolean isValid() {
128         return isValid;
129     }
130
131     private boolean checkValueType() {
132         if (type.isCongruentType(value, mask) == false) {
133             String valueClass = (value == null) ? "null" : value.getClass()
134                     .getSimpleName();
135             String maskClass = (mask == null) ? "null" : mask.getClass()
136                     .getSimpleName();
137             String error = "Invalid match field's value or mask types.For field: "
138                     + type.id()
139                     + " Expected:"
140                     + type.dataType().getSimpleName()
141                     + " or equivalent,"
142                     + " Got:(" + valueClass + "," + maskClass + ")";
143             throwException(error);
144             return false;
145         }
146         return true;
147     }
148
149     private boolean checkValues() {
150         if (type.isValid(value, mask) == false) {
151             String maskString = (mask == null) ? "null" : ("0x" + Integer
152                     .toHexString(Integer.parseInt(mask.toString())));
153             String error = "Invalid match field's value or mask assignement.For field: "
154                     + type.id()
155                     + " Expected: "
156                     + type.getRange()
157                     + ", Got:(0x"
158                     + Integer.toHexString(Integer.parseInt(value.toString()))
159                     + "," + maskString + ")";
160
161             throwException(error);
162             return false;
163         }
164         return true;
165     }
166
167     private static void throwException(String error) {
168         try {
169             throw new Exception(error);
170         } catch (Exception e) {
171             logger.error(e.getMessage());
172         }
173     }
174
175     @Override
176     public MatchField clone() {
177         MatchField cloned = null;
178         try {
179             cloned = (MatchField) super.clone();
180             if (value instanceof byte[]) {
181                 cloned.value = ((byte[]) this.value).clone();
182                 if (this.mask != null) {
183                     cloned.mask = ((byte[]) this.mask).clone();
184                 }
185             }
186         } catch (CloneNotSupportedException e) {
187             e.printStackTrace();
188         }
189         return cloned;
190     }
191
192     @Override
193     public int hashCode() {
194         return HashCodeBuilder.reflectionHashCode(this);
195     }
196
197     @Override
198     public boolean equals(Object obj) {
199         return EqualsBuilder.reflectionEquals(this, obj);
200     }
201
202     @Override
203     public String toString() {
204         return type + "(" + getValueString() + "," + getMaskString() + ")";
205     }
206 }