| 30 |
ashish |
1 |
/**
|
|
|
2 |
* Licensed to the Apache Software Foundation (ASF) under one
|
|
|
3 |
* or more contributor license agreements. See the NOTICE file
|
|
|
4 |
* distributed with this work for additional information
|
|
|
5 |
* regarding copyright ownership. The ASF licenses this file
|
|
|
6 |
* to you under the Apache License, Version 2.0 (the
|
|
|
7 |
* "License"); you may not use this file except in compliance
|
|
|
8 |
* with the License. You may obtain a copy of the License at
|
|
|
9 |
*
|
|
|
10 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
11 |
*
|
|
|
12 |
* Unless required by applicable law or agreed to in writing, software
|
|
|
13 |
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
14 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
15 |
* See the License for the specific language governing permissions and
|
|
|
16 |
* limitations under the License.
|
|
|
17 |
*/
|
|
|
18 |
package org.apache.thrift;
|
|
|
19 |
|
|
|
20 |
import java.util.ArrayList;
|
|
|
21 |
import java.util.HashMap;
|
|
|
22 |
import java.util.HashSet;
|
|
|
23 |
import java.util.List;
|
|
|
24 |
import java.util.Map;
|
|
|
25 |
import java.util.Set;
|
|
|
26 |
|
|
|
27 |
import org.apache.thrift.protocol.TField;
|
|
|
28 |
import org.apache.thrift.protocol.TProtocol;
|
|
|
29 |
import org.apache.thrift.protocol.TProtocolException;
|
|
|
30 |
import org.apache.thrift.protocol.TStruct;
|
|
|
31 |
|
|
|
32 |
public abstract class TUnion<F extends TFieldIdEnum> implements TBase<F> {
|
|
|
33 |
|
|
|
34 |
protected Object value_;
|
|
|
35 |
protected F setField_;
|
|
|
36 |
|
|
|
37 |
protected TUnion() {
|
|
|
38 |
setField_ = null;
|
|
|
39 |
value_ = null;
|
|
|
40 |
}
|
|
|
41 |
|
|
|
42 |
protected TUnion(F setField, Object value) {
|
|
|
43 |
setFieldValue(setField, value);
|
|
|
44 |
}
|
|
|
45 |
|
|
|
46 |
protected TUnion(TUnion<F> other) {
|
|
|
47 |
if (!other.getClass().equals(this.getClass())) {
|
|
|
48 |
throw new ClassCastException();
|
|
|
49 |
}
|
|
|
50 |
setField_ = other.setField_;
|
|
|
51 |
value_ = deepCopyObject(other.value_);
|
|
|
52 |
}
|
|
|
53 |
|
|
|
54 |
private static Object deepCopyObject(Object o) {
|
|
|
55 |
if (o instanceof TBase) {
|
|
|
56 |
return ((TBase)o).deepCopy();
|
|
|
57 |
} else if (o instanceof byte[]) {
|
|
|
58 |
byte[] other_val = (byte[])o;
|
|
|
59 |
byte[] this_val = new byte[other_val.length];
|
|
|
60 |
System.arraycopy(other_val, 0, this_val, 0, other_val.length);
|
|
|
61 |
return this_val;
|
|
|
62 |
} else if (o instanceof List) {
|
|
|
63 |
return deepCopyList((List)o);
|
|
|
64 |
} else if (o instanceof Set) {
|
|
|
65 |
return deepCopySet((Set)o);
|
|
|
66 |
} else if (o instanceof Map) {
|
|
|
67 |
return deepCopyMap((Map)o);
|
|
|
68 |
} else {
|
|
|
69 |
return o;
|
|
|
70 |
}
|
|
|
71 |
}
|
|
|
72 |
|
|
|
73 |
private static Map deepCopyMap(Map<Object, Object> map) {
|
|
|
74 |
Map copy = new HashMap();
|
|
|
75 |
for (Map.Entry<Object, Object> entry : map.entrySet()) {
|
|
|
76 |
copy.put(deepCopyObject(entry.getKey()), deepCopyObject(entry.getValue()));
|
|
|
77 |
}
|
|
|
78 |
return copy;
|
|
|
79 |
}
|
|
|
80 |
|
|
|
81 |
private static Set deepCopySet(Set set) {
|
|
|
82 |
Set copy = new HashSet();
|
|
|
83 |
for (Object o : set) {
|
|
|
84 |
copy.add(deepCopyObject(o));
|
|
|
85 |
}
|
|
|
86 |
return copy;
|
|
|
87 |
}
|
|
|
88 |
|
|
|
89 |
private static List deepCopyList(List list) {
|
|
|
90 |
List copy = new ArrayList(list.size());
|
|
|
91 |
for (Object o : list) {
|
|
|
92 |
copy.add(deepCopyObject(o));
|
|
|
93 |
}
|
|
|
94 |
return copy;
|
|
|
95 |
}
|
|
|
96 |
|
|
|
97 |
public F getSetField() {
|
|
|
98 |
return setField_;
|
|
|
99 |
}
|
|
|
100 |
|
|
|
101 |
public Object getFieldValue() {
|
|
|
102 |
return value_;
|
|
|
103 |
}
|
|
|
104 |
|
|
|
105 |
public Object getFieldValue(F fieldId) {
|
|
|
106 |
if (fieldId != setField_) {
|
|
|
107 |
throw new IllegalArgumentException("Cannot get the value of field " + fieldId + " because union's set field is " + setField_);
|
|
|
108 |
}
|
|
|
109 |
|
|
|
110 |
return getFieldValue();
|
|
|
111 |
}
|
|
|
112 |
|
|
|
113 |
public Object getFieldValue(int fieldId) {
|
|
|
114 |
return getFieldValue(enumForId((short)fieldId));
|
|
|
115 |
}
|
|
|
116 |
|
|
|
117 |
public boolean isSet() {
|
|
|
118 |
return setField_ != null;
|
|
|
119 |
}
|
|
|
120 |
|
|
|
121 |
public boolean isSet(F fieldId) {
|
|
|
122 |
return setField_ == fieldId;
|
|
|
123 |
}
|
|
|
124 |
|
|
|
125 |
public boolean isSet(int fieldId) {
|
|
|
126 |
return isSet(enumForId((short)fieldId));
|
|
|
127 |
}
|
|
|
128 |
|
|
|
129 |
public void read(TProtocol iprot) throws TException {
|
|
|
130 |
setField_ = null;
|
|
|
131 |
value_ = null;
|
|
|
132 |
|
|
|
133 |
iprot.readStructBegin();
|
|
|
134 |
|
|
|
135 |
TField field = iprot.readFieldBegin();
|
|
|
136 |
|
|
|
137 |
value_ = readValue(iprot, field);
|
|
|
138 |
if (value_ != null) {
|
|
|
139 |
setField_ = enumForId(field.id);
|
|
|
140 |
}
|
|
|
141 |
|
|
|
142 |
iprot.readFieldEnd();
|
|
|
143 |
// this is so that we will eat the stop byte. we could put a check here to
|
|
|
144 |
// make sure that it actually *is* the stop byte, but it's faster to do it
|
|
|
145 |
// this way.
|
|
|
146 |
iprot.readFieldBegin();
|
|
|
147 |
iprot.readStructEnd();
|
|
|
148 |
}
|
|
|
149 |
|
|
|
150 |
public void setFieldValue(F fieldId, Object value) {
|
|
|
151 |
checkType(fieldId, value);
|
|
|
152 |
setField_ = fieldId;
|
|
|
153 |
value_ = value;
|
|
|
154 |
}
|
|
|
155 |
|
|
|
156 |
public void setFieldValue(int fieldId, Object value) {
|
|
|
157 |
setFieldValue(enumForId((short)fieldId), value);
|
|
|
158 |
}
|
|
|
159 |
|
|
|
160 |
public void write(TProtocol oprot) throws TException {
|
|
|
161 |
if (getSetField() == null || getFieldValue() == null) {
|
|
|
162 |
throw new TProtocolException("Cannot write a TUnion with no set value!");
|
|
|
163 |
}
|
|
|
164 |
oprot.writeStructBegin(getStructDesc());
|
|
|
165 |
oprot.writeFieldBegin(getFieldDesc(setField_));
|
|
|
166 |
writeValue(oprot, setField_, value_);
|
|
|
167 |
oprot.writeFieldEnd();
|
|
|
168 |
oprot.writeFieldStop();
|
|
|
169 |
oprot.writeStructEnd();
|
|
|
170 |
}
|
|
|
171 |
|
|
|
172 |
/**
|
|
|
173 |
* Implementation should be generated so that we can efficiently type check
|
|
|
174 |
* various values.
|
|
|
175 |
* @param setField
|
|
|
176 |
* @param value
|
|
|
177 |
*/
|
|
|
178 |
protected abstract void checkType(F setField, Object value) throws ClassCastException;
|
|
|
179 |
|
|
|
180 |
/**
|
|
|
181 |
* Implementation should be generated to read the right stuff from the wire
|
|
|
182 |
* based on the field header.
|
|
|
183 |
* @param field
|
|
|
184 |
* @return
|
|
|
185 |
*/
|
|
|
186 |
protected abstract Object readValue(TProtocol iprot, TField field) throws TException;
|
|
|
187 |
|
|
|
188 |
protected abstract void writeValue(TProtocol oprot, F setField, Object value) throws TException;
|
|
|
189 |
|
|
|
190 |
protected abstract TStruct getStructDesc();
|
|
|
191 |
|
|
|
192 |
protected abstract TField getFieldDesc(F setField);
|
|
|
193 |
|
|
|
194 |
protected abstract F enumForId(short id);
|
|
|
195 |
|
|
|
196 |
@Override
|
|
|
197 |
public String toString() {
|
|
|
198 |
Object v = getFieldValue();
|
|
|
199 |
String vStr = null;
|
|
|
200 |
if (v instanceof byte[]) {
|
|
|
201 |
vStr = bytesToStr((byte[])v);
|
|
|
202 |
} else {
|
|
|
203 |
vStr = v.toString();
|
|
|
204 |
}
|
|
|
205 |
return "<" + this.getClass().getSimpleName() + " " + getFieldDesc(getSetField()).name + ":" + vStr + ">";
|
|
|
206 |
}
|
|
|
207 |
|
|
|
208 |
private static String bytesToStr(byte[] bytes) {
|
|
|
209 |
StringBuilder sb = new StringBuilder();
|
|
|
210 |
int size = Math.min(bytes.length, 128);
|
|
|
211 |
for (int i = 0; i < size; i++) {
|
|
|
212 |
if (i != 0) {
|
|
|
213 |
sb.append(" ");
|
|
|
214 |
}
|
|
|
215 |
String digit = Integer.toHexString(bytes[i]);
|
|
|
216 |
sb.append(digit.length() > 1 ? digit : "0" + digit);
|
|
|
217 |
}
|
|
|
218 |
if (bytes.length > 128) {
|
|
|
219 |
sb.append(" ...");
|
|
|
220 |
}
|
|
|
221 |
return sb.toString();
|
|
|
222 |
}
|
|
|
223 |
}
|