blob: ac48c8d4a76f5da59a4f6454c3a97f8cbba909dd [file] [log] [blame]
Yotam Harcholf3f11152013-09-05 16:47:16 -07001package org.projectfloodlight.openflow.protocol;
2
3import java.util.EnumMap;
4import java.util.Iterator;
5import java.util.List;
6import java.util.Map;
7
8import org.jboss.netty.buffer.ChannelBuffer;
9import org.projectfloodlight.openflow.exceptions.OFParseError;
10import org.projectfloodlight.openflow.protocol.match.MatchField;
11import org.projectfloodlight.openflow.protocol.match.MatchFields;
12import org.projectfloodlight.openflow.types.OFValueType;
13import org.projectfloodlight.openflow.util.ChannelUtils;
14import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
15
16import com.google.common.collect.ImmutableMap;
17
18public class OFOxmList implements Iterable<OFOxm<?>>, Writeable {
19 private final Map<MatchFields, OFOxm<?>> oxmMap;
20
21 public final static OFOxmList EMPTY = new OFOxmList(ImmutableMap.<MatchFields, OFOxm<?>>of());
22
23 private OFOxmList(Map<MatchFields, OFOxm<?>> oxmMap) {
24 this.oxmMap = oxmMap;
25 }
26
27 @SuppressWarnings("unchecked")
28 public <T extends OFValueType<T>> OFOxm<T> get(MatchField<T> matchField) {
29 return (OFOxm<T>) oxmMap.get(matchField.id);
30 }
31
32 public static class Builder {
33 private final Map<MatchFields, OFOxm<?>> oxmMap;
34
35 public Builder() {
36 oxmMap = new EnumMap<MatchFields, OFOxm<?>>(MatchFields.class);
37 }
38
39 public Builder(EnumMap<MatchFields, OFOxm<?>> oxmMap) {
40 this.oxmMap = oxmMap;
41 }
42
43 public <T extends OFValueType<T>> void set(OFOxm<T> oxm) {
44 oxmMap.put(oxm.getMatchField().id, oxm);
45 }
46
47 public <T extends OFValueType<T>> void unset(MatchField<T> matchField) {
48 oxmMap.remove(matchField.id);
49 }
50
51 public OFOxmList build() {
52 return new OFOxmList(oxmMap);
53 }
54 }
55
56 @Override
57 public Iterator<OFOxm<?>> iterator() {
58 return oxmMap.values().iterator();
59 }
60
61 public static OFOxmList ofList(List<OFOxm<?>> oxmList) {
62 Map<MatchFields, OFOxm<?>> map = new EnumMap<MatchFields, OFOxm<?>>(
63 MatchFields.class);
64 for (OFOxm<?> o : oxmList) {
65 // TODO: if fully masked, ignore oxm.
66 map.put(o.getMatchField().id, o);
67 }
68 return new OFOxmList(map);
69 }
70
71 public static OFOxmList of(OFOxm<?>... oxms) {
72 Map<MatchFields, OFOxm<?>> map = new EnumMap<MatchFields, OFOxm<?>>(
73 MatchFields.class);
74 for (OFOxm<?> o : oxms) {
75 // TODO: if fully masked, ignore oxm.
76 map.put(o.getMatchField().id, o);
77 }
78 return new OFOxmList(map);
79 }
80
81 public static OFOxmList readFrom(ChannelBuffer bb, int length,
82 OFMessageReader<OFOxm<?>> reader) throws OFParseError {
83 return ofList(ChannelUtils.readList(bb, length, reader));
84 }
85
86 @Override
87 public void writeTo(ChannelBuffer bb) {
88 for (OFOxm<?> o : this) {
89 o.writeTo(bb);
90 }
91 }
92
93 public OFOxmList.Builder createBuilder() {
94 return new OFOxmList.Builder(new EnumMap<MatchFields, OFOxm<?>>(oxmMap));
95 }
96
97 @Override
98 public int hashCode() {
99 final int prime = 31;
100 int result = 1;
101 result = prime * result + ((oxmMap == null) ? 0 : oxmMap.hashCode());
102 return result;
103 }
104
105 @Override
106 public boolean equals(Object obj) {
107 if (this == obj)
108 return true;
109 if (obj == null)
110 return false;
111 if (getClass() != obj.getClass())
112 return false;
113 OFOxmList other = (OFOxmList) obj;
114 if (oxmMap == null) {
115 if (other.oxmMap != null)
116 return false;
117 } else if (!oxmMap.equals(other.oxmMap))
118 return false;
119 return true;
120 }
121
122 @Override
123 public String toString() {
124 return "OFOxmList" + oxmMap;
125 }
126
127
128}