Initial opendaylight infrastructure commit!!
[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 org.apache.commons.lang3.builder.EqualsBuilder;
13 import org.apache.commons.lang3.builder.HashCodeBuilder;
14 import org.opendaylight.controller.sal.utils.HexEncode;
15 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory;
17
18 /**
19  * Represents the generic matching field
20  *
21  *
22  *
23  */
24 public class MatchField implements Cloneable {
25     private static final Logger logger = LoggerFactory
26             .getLogger(MatchField.class);
27     private MatchType type; // the field we want to match
28     private Object value; // the value of the field we want to match
29     private Object mask; // the value of the mask we want to match on the specified field
30     private transient boolean isValid;
31
32     /**
33      * Mask based match constructor
34      *
35      * @param type
36      * @param value
37      * @param mask   has to be of the same class type of value. A null mask means full match
38      */
39     public MatchField(MatchType type, Object value, Object mask) {
40         this.type = type;
41         this.value = value;
42         this.mask = mask;
43         this.isValid = checkValueType() && checkValues(); // Keep this logic, value checked only if type check is fine
44     }
45
46     /**
47      * Full match constructor
48      *
49      * @param type
50      * @param value
51      */
52     public MatchField(MatchType type, Object value) {
53         this.type = type;
54         this.value = value;
55         this.mask = null;
56         this.isValid = checkValueType() && checkValues(); // Keep this logic, value checked only if type check is fine
57     }
58
59     /**
60      * Returns the value set for this match field
61      *
62      * @return
63      */
64     public Object getValue() {
65         return value;
66     }
67
68     /**
69      * Returns the type field this match field object is for
70      *
71      * @return
72      */
73     public MatchType getType() {
74         return type;
75     }
76
77     /**
78      * Returns the mask value set for this field match
79      * A null mask means this is a full match
80      * @return
81      */
82     public Object getMask() {
83         return mask;
84     }
85
86     /**
87      * Returns the bitmask set for this field match
88      *
89      * @return
90      */
91     public long getBitMask() {
92         return type.getBitMask(mask);
93     }
94
95     /**
96      * Returns whether the field match configuration is valid or not
97      *
98      * @return
99      */
100     public boolean isValid() {
101         return isValid;
102     }
103
104     private boolean checkValueType() {
105         if (type.isCongruentType(value, mask) == false) {
106             String valueClass = (value == null) ? "null" : value.getClass()
107                     .getSimpleName();
108             String maskClass = (mask == null) ? "null" : mask.getClass()
109                     .getSimpleName();
110             String error = "Invalid match field's value or mask types.For field: "
111                     + type.id()
112                     + " Expected:"
113                     + type.dataType().getSimpleName()
114                     + " or equivalent,"
115                     + " Got:(" + valueClass + "," + maskClass + ")";
116             throwException(error);
117             return false;
118         }
119         return true;
120     }
121
122     private boolean checkValues() {
123         if (type.isValid(value, mask) == false) {
124             String maskString = (mask == null) ? "null" : ("0x" + Integer
125                     .toHexString(Integer.parseInt(mask.toString())));
126             String error = "Invalid match field's value or mask assignement.For field: "
127                     + type.id()
128                     + " Expected: "
129                     + type.getRange()
130                     + ", Got:(0x"
131                     + Integer.toHexString(Integer.parseInt(value.toString()))
132                     + "," + maskString + ")";
133
134             throwException(error);
135             return false;
136         }
137         return true;
138     }
139
140     private static void throwException(String error) {
141         try {
142             throw new Exception(error);
143         } catch (Exception e) {
144             logger.error(e.getMessage());
145         }
146     }
147
148     @Override
149     public MatchField clone() {
150         MatchField cloned = null;
151         try {
152             cloned = (MatchField) super.clone();
153             if (value instanceof byte[]) {
154                 cloned.value = ((byte[]) this.value).clone();
155                 if (this.mask != null) {
156                     cloned.mask = ((byte[]) this.mask).clone();
157                 }
158             }
159         } catch (CloneNotSupportedException e) {
160             e.printStackTrace();
161         }
162         return cloned;
163     }
164
165     @Override
166     public int hashCode() {
167         return HashCodeBuilder.reflectionHashCode(this);
168     }
169
170     @Override
171     public boolean equals(Object obj) {
172         return EqualsBuilder.reflectionEquals(this, obj);
173     }
174
175     @Override
176     public String toString() {
177         String valueString = (value == null) ? "null"
178                 : (value instanceof byte[]) ? HexEncode
179                         .bytesToHexString((byte[]) value) : value.toString();
180         String maskString = (mask == null) ? "null"
181                 : (mask instanceof byte[]) ? HexEncode
182                         .bytesToHexString((byte[]) mask) : mask.toString();
183
184         return type + "(" + valueString + "," + maskString + ")";
185     }
186 }